473,734 Members | 2,824 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

trouble subclassing str

I'd like to subclass the built-in str type. For example:

--

class MyString(str):

def __init__(self, txt, data):
super(MyString, self).__init__( txt)
self.data = data

if __name__ == '__main__':

s1 = MyString("some text", 100)

--

but I get the error:

Traceback (most recent call last):
File "MyString.p y", line 27, in ?
s1 = MyString("some text", 12)
TypeError: str() takes at most 1 argument (2 given)

I am using Python 2.3 on OS X. Ideas?

Jul 19 '05 #1
11 3476
My first thought is "make sure that subclassing str is really what you
want to do." Here is a place where I have a subclass of str that
really is a special kind of str:

class PaddedStr(str):
def __new__(cls,s,l ,padc=' '):
if l > len(s):
s2 = "%s%s" % (s,padc*(l-len(s)))
return str.__new__(str ,s2)
else:
return str.__new__(str ,s)

print ">%s<" % PaddedStr("aaa" ,10)
print ">%s<" % PaddedStr("aaa" ,8,".")
(When subclassing str, you have to call str.__new__ from your
subclass's __new__ method, since str's are immutable. Don't forget
that __new__ requires a first parameter which is the input class. I
think the rest of my example is pretty self-explanatory.)

But if you are subclassing str just so that you can easily print your
objects, look at implementing the __str__ instance method on your
class. Reserve inheritance for true "is-a" relationships. Often,
inheritance is misapplied when the designer really means "has-a" or
"is-implemented-using-a", and in these cases, the supposed superclass
is better referenced using a member variable, and delegating to it.

-- Paul

Jul 19 '05 #2
On Thu, 23 Jun 2005 12:25:58 -0700, Paul McGuire wrote:
But if you are subclassing str just so that you can easily print your
objects, look at implementing the __str__ instance method on your
class. Reserve inheritance for true "is-a" relationships. Often,
inheritance is misapplied when the designer really means "has-a" or
"is-implemented-using-a", and in these cases, the supposed superclass
is better referenced using a member variable, and delegating to it.


Since we've just be talking about buzzwords in another thread, and the
difficulty self-taught folks have in knowing what they are, I don't
suppose somebody would like to give a simple, practical example of what
Paul means?

I'm going to take a punt here and guess. Instead of creating a sub-class
of str, Paul suggests you simply create a class:

class MyClass:
def __init__(self, value):
# value is expected to be a string
self.value = self.mangle(val ue)
def mangle(self, s):
# do work on s to make sure it looks the way you want it to look
return "*** " + s + " ***"
def __str__(self):
return self.value

(only with error checking etc for production code).

Then you use it like this:

py> myprintablestr = MyClass("Lovely Spam!")
py> print myprintablestr
*** Lovely Spam!!! ***

Am I close?
--
Steven

Jul 19 '05 #3
In article <pa************ *************** *@REMOVETHIScyb er.com.au>,
Steven D'Aprano <st***@REMOVETH IScyber.com.au> wrote:
On Thu, 23 Jun 2005 12:25:58 -0700, Paul McGuire wrote:
But if you are subclassing str just so that you can easily print your
objects, look at implementing the __str__ instance method on your
class. Reserve inheritance for true "is-a" relationships. Often,
inheritance is misapplied when the designer really means "has-a" or
"is-implemented-using-a", and in these cases, the supposed superclass
is better referenced using a member variable, and delegating to it.


Since we've just be talking about buzzwords in another thread, and the
difficulty self-taught folks have in knowing what they are, I don't
suppose somebody would like to give a simple, practical example of what
Paul means?

I'm going to take a punt here and guess. Instead of creating a sub-class
of str, Paul suggests you simply create a class:

class MyClass:
def __init__(self, value):
# value is expected to be a string
self.value = self.mangle(val ue)
def mangle(self, s):
# do work on s to make sure it looks the way you want it to look
return "*** " + s + " ***"
def __str__(self):
return self.value

(only with error checking etc for production code).

Then you use it like this:

py> myprintablestr = MyClass("Lovely Spam!")
py> print myprintablestr
*** Lovely Spam!!! ***

Am I close?


That's how I read it, with "value" as the member variable
that you delegate to.

Left unexplained is ``true "is-a" relationships'' . Sounds
like an implicit contradiction -- you can't implement
something that truly is something else. Without that, and
maybe a more nuanced replacement for "is-implemented-using-a",
I don't see how you could really be sure of the point.

Donn Cave, do**@u.washingt on.edu
Jul 19 '05 #4
Brent wrote:
I'd like to subclass the built-in str type. For example:
You'd like to build this weird-looking semi-mutable object as a
perceived solution to what problem? Perhaps an alternative is a class of
objects which have a "key" (your current string value) and some data
attributes? Maybe simply a dict ... adict["some text"] = 100?
class MyString(str):

def __init__(self, txt, data):
super(MyString, self).__init__( txt)
self.data = data

if __name__ == '__main__':

s1 = MyString("some text", 100)
but I get the error:

Traceback (most recent call last):
File "MyString.p y", line 27, in ?
s1 = MyString("some text", 12)
TypeError: str() takes at most 1 argument (2 given)

I am using Python 2.3 on OS X. Ideas?


__init__ is not what you want.

If you had done some basic debugging before posting (like putting a
print statement in your __init__), you would have found out that it is
not even being called.

Suggestions:

1. Read the manual section on __new__
2. Read & run the following:

class MyString(str):

def __new__(cls, txt, data):
print "MyString.__new __:"
print "cls is", repr(cls)
theboss = super(MyString, cls)
print "theboss:", repr(theboss)
new_instance = theboss.__new__ (cls, txt)
print "new_instance:" , repr(new_instan ce)
new_instance.da ta = data
return new_instance

if __name__ == '__main__':

s1 = MyString("some text", 100)
print "s1:", type(s1), repr(s1)
print "s1.data:", s1.data

3. Note, *if* you provide an __init__ method, it will be called
[seemingly redundantly???] after __new__ has returned.

HTH,
John
Jul 19 '05 #5
Dang, that class should be:

class PaddedStr(str):
def __new__(cls,s,l ,padc=' '):
if l > len(s):
s2 = "%s%s" % (s,padc*(l-len(s)))
return str.__new__(cls ,s2)
else:
return str.__new__(cls ,s)

-- Paul

Jul 19 '05 #6
Donn Cave wrote:
Left unexplained is ``true "is-a" relationships'' . Sounds
like an implicit contradiction -- you can't implement
something that truly is something else. Without that, and
maybe a more nuanced replacement for "is-implemented-using-a",
I don't see how you could really be sure of the point.


Try this article for an explanation of is-a:
http://www.objectmentor.com/resources/articles/lsp.pdf

IMO Robert Martin explains what good OO design is better than anyone else. His book "Agile Software Development" is excellent.

Kent
Jul 19 '05 #7
>From purely Python terms, there is a distinction that one of these
classes (PaddedStr) is immutable, while the other is not. Python only
permits immutable objects to act as dictionary keys, so this would one
thing to differentiate these two approaches.

But on a more abstract, implementation-independent level, this is a
distinction of inheritance vs. composition and delegation. Inheritance
was one of the darling concepts in the early days of O-O programming,
with promises of reusability and development speed. But before long,
it turned out that inheritance comes with some unfriendly baggage -
dependencies between subclasses and superclasses made refactoring more
difficult, and modifications to supertypes had unwanted effects on
subclasses. Sometimes subclasses would use some backdoor knowledge of
the supertype data, thereby limiting flexibility in the superclass -
this phenomenon is often cited as "inheritanc e breaks encapsulation."

One check for good inheritance design is the Liskov Substitution
Principle (LSP) (Thanks for the Robert Martin link, Kent - you beat me
to it). Borrowing from the Wiki-pedia:
"In general, the principle mandates that at all times objects from a
class can be swapped with objects from an inheriting class, without the
user noticing any other new behaviour. It has effects on the paradigms
of design by contract, especially regarding to specification:
- postconditions for methods in the subclass should be more strict than
those in the superclass
- preconditions for methods in the subclass should be less strict than
those in the superclass
- no new exceptions should be introduced in the subclass"
(http://en.wikipedia.org/wiki/Liskov_...tion_principle)

One thing I like about this concept is that is fairly indepedent of
language or implementation features. I get the feeling that many such
rules/guidelines seem to be inspired by limitations or gimmicks that
are found in programming language X (usually C++ or Java), and then
mistakenly generalized to be universal O-O truths.

Looking back to PaddedStr vs. MyString, you can see that PaddedStr will
substitute for str, and for that matter, the MyString behavior that is
given could be a reasonable subclass of str, although maybe better
named StarredStr. But let's take a slightly different MyString, one
like this, where we subclass str to represent a person's name:

class Person(str):
def __new__(cls,s,d ata):
self = str.__new__(cls ,s)
self.age = data
return self

p = Person("Bob",10 )
print p,p.age

This is handy enough for printing out a Person and getting their name.
But consider a father and son, both named "Bob".

p1 = Person("Bob",10 )
p2 = Person("Bob",35 ) # p1's dad, also named Bob
print p1 == p2 # prints 'true', should it?
print p1 is p2 # prints 'false'
Most often, I see "is-a" confused with "is-implemented-using-a". A
developer decides that there is some benefit (reduced storage, perhaps)
of modeling a zip code using an integer, and feels the need to define
some class like:

class ZipCode(int):
def lookupState(sel f):
...

But zip codes *aren't* integers, they just happen to be numeric - there
is no sense in supporting zip code arithmetic, nor in using zip codes
as slice indices, etc. And there are other warts, such as printing zip
codes with leading zeroes (like they have in Maine).

So when, about once a month we see on c.l.py "I'm having trouble
sub-classing <built-in class XYZ>," I can't help but wonder if telling
the poster how to sub-class an XYZ is really doing the right thing.

In this thread, the OP wanted to extend str with something that was
constructable with two arguments, a string and an integer, as in s1 =
MyString("some text", 100). I tried to propose a case that would be a
good example of inheritance, where the integer would be used to define
and/or constrain some str attribute. A *bad* example of inheritance
would have been one where the 100 had some independent characteristic,
like a font size, or an age value to be associated with a string that
happens to contain a person's name. In fact, looking at the proposed
MyClass, this seems to be the direction he was headed.

When *should* you use inheritance? Well, for a while, there was such
backlash that the response was "Never". Personally, I use inheritance
in cases where I have adopted a design pattern that incorporates it,
such as Strategy; otherwise, I tend not to use it. (For those of you
who use my pyparsing package, it is loaded with the Strategy pattern.
The base class ParserElement defines an abstract do-nothing parsing
implementation, which is overridden in subclasses such as Literal,
Word, and Group. All derived instances are treated like the base
ParserElement, with each subclass providing its own specialized
parseImpl or postParse behavior, so any subclass can be substituted for
the base ParserElement, satisfying LSP.)

I think the current conventional wisdom is "prefer composition over
inheritance" - never say "never"! :)

-- Paul

Jul 19 '05 #8
In article <11************ **********@z14g 2000cwz.googleg roups.com>,
"Paul McGuire" <pt***@austin.r r.com> wrote:
[ ... lots of interesting discussion removed ... ]
Most often, I see "is-a" confused with "is-implemented-using-a". A
developer decides that there is some benefit (reduced storage, perhaps)
of modeling a zip code using an integer, and feels the need to define
some class like:

class ZipCode(int):
def lookupState(sel f):
...

But zip codes *aren't* integers, they just happen to be numeric - there
is no sense in supporting zip code arithmetic, nor in using zip codes
as slice indices, etc. And there are other warts, such as printing zip
codes with leading zeroes (like they have in Maine).


I agree, but I'm not sure how easily this kind of reasoning
can be applied more generally to objects we write. Take for
example an indexed data structure, that's generally similar
to a dictionary but may compute some values. I think it's
common practice in Python to implement this just as I'm sure
you would propose, with composition. But is that because it
fails your "is-a" test? What is-a dictionary, or is-not-a
dictionary? If you ask me, there isn't any obvious principle,
it's just a question of how we arrive at a sound implementation --
and that almost always militates against inheritance, because
of liabilities you mentioned elsewhere in your post, but in the
end it depends on the details of the implementation.

Donn Cave, do**@u.washinto n.edu
Jul 19 '05 #9
Look at the related post, on keeping key-key pairs in a dictionary.
Based on our discussion in this thread, I created a subclass of dict
called SymmetricDict, that, when storing symDict["A"] = 1, implicitly
saves the backward looking symDict[1] = "A".

I chose to inherit from dict, in part just to see what it would look
like. In doing so, SymmetricDict automagically gets methods such as
keys(), values(), items(), contains(), and support for len, "key in
dict", etc. However, I think SymmetricDict breaks (or at least bends)
LSP, in that there are some cases where SymmetricDict has some
surprising non-dict behavior. For instance, if I do:

d = dict()
d["A"] = 1
d["B"] = 1
print d.keys()

I get ["A", "B"]. But a SymmetricDict is rather strange.

sd = SymmetricDict()
sd["A"] = 1
sd["B"] = 1
print sd.keys()

gives ["B",1]. The second assignment wiped out the association of "A"
to 1. (This reminds me of some maddening O-O discussions I used to
have at a former place of employment, in which one developer cited
similar behavior for not having Square inherit from Rectangle - calling
Square.setWidth () would have to implicitly call setHeight() and vice
versa, in order to maintain its squarishness, and thereby broke Liskov.
I withdrew from the debate, citing lack of context that would have
helped resolve how things should go. At best, you can *probably* say
that both inherit from Shape, and can be drawn, have an area, a
bounding rectangle, etc., but not either inherits from the other.
Unless I'm mistaken, I think Robert Martin has some discussion on this
example also.)

So in sum, I'd say that I would be comfortable having SymmetricDict
extend dict *in my own code*, but that such a beast probably should
*not* be part of the standard Python distribution, in whose scope the
non-dictishness of SymmetricDict cannot be predicted. (And maybe this
gives us some clue about the difficulty of deciding what and what not
to put in to the Python language and libs.)

-- Paul

Jul 19 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
2731
by: WhiteRavenEye | last post by:
Why can't I subclass any window except mine in VB? Do I have to write dll for this? I've tried to subclass it with SetWindowLong but without success... Does anyone know how to subclass window ANY window in VB? Thanks...
4
1848
by: GrelEns | last post by:
hello, i wonder if this possible to subclass a list or a tuple and add more attributes ? also does someone have a link to how well define is own iterable object ? what i was expecting was something like : >>> t = Test('anAttributeValue', ) >>> t.anAttribute
2
1508
by: David Vaughan | last post by:
I'm using v2.3, and trying to write to text files, but with a maximum line length. So, if a line is getting too long, a suitable ' ' character is replaced by a new line. I'm subclassing the file class, and, as long as I just use the write method, this works fine. But "print >>" doesn't behave as I want: class max_width_file(file): def write(self, txt): print "In max_width_file's write method." fout = max_width_file('foo.txt', 'w')
2
5160
by: BJörn Lindqvist | last post by:
A problem I have occured recently is that I want to subclass builtin types. Especially subclassing list is very troublesome to me. But I can't find the right syntax to use. Take for example this class which is supposed to be a representation of a genome: class Genome(list): def __init__(self): list.__init__(self) self = ....
3
1692
by: Peter Olsen | last post by:
I want to define a class "point" as a subclass of complex. When I create an instance sample = point(<arglist>) I want "sample" to "be" a complex number, but with its real and imaginary parts computed in point()'s __init__ function with their values based on the arglist. I want to compute with point instances as though they were native complex numbers, but I want to be able to
3
1544
by: alotcode | last post by:
Hello: What is 'interprocess subclassing'? To give more context, I am writing in reference to the following remark: With the advent of the Microsoft Win32 API, interprocess subclassing was discouraged and made it a bit harder to code (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwebgen/html/bho.asp) Thank you for your help.
5
6488
by: Pieter Linden | last post by:
Hi, This question refers sort of to Rebecca Riordan's article on Access web about subclassing entities: http://www.mvps.org/access/tables/tbl0013.htm How practical is this? I am writing a database to track Computer equipment/inventory as well as other devices. Computers, of course, have software installed, so I want to keep track of that. I was
16
2076
by: manatlan | last post by:
I've got an instance of a class, ex : b=gtk.Button() I'd like to add methods and attributes to my instance "b". I know it's possible by hacking "b" with setattr() methods. But i'd like to do it with inheritance, a kind of "dynamic subclassing", without subclassing the class, only this instance "b" ! In fact, i've got my instance "b", and another class "MoreMethods"
5
2531
by: Ray | last post by:
Hi all, I am thinking of subclassing the standard string class so I can do something like: mystring str; .... str.toLower (); A quick search on this newsgroup has found messages by others
0
8946
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
1
9237
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9184
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8187
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6737
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6033
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
1
3262
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2729
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2180
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.