How to initialize instances of subclass of 'str'?
Tim Peters
tim.peters at gmail.com
Sat Aug 7 00:51:47 EDT 2004
[Kenneth McDonald]
> I'm attempting to create a subclass of 'str' that I can abitrarily
> initialize at creation time. As an illustration, this gives the
> flavor of what I'm trying to do:
>
> class AlwaysLower(str):
> def __init__(self, s):
> str.__init__(self, s.lower())
>
> The idea is that an AlwaysLower instance should be a string
> which is always lowercase; AlwaysLower('A') -> 'a',
> AlwaysLower('b') -> 'b', etc. (Of course, the resultant
> instances are not _just_ strings, but since they are
> subclasses of str, they can be treated and viewed as strings,
> as I implicitly do above.)
>
> Unfortunately, the above code doesn't work; the resultant
> instance's string value is always s, i.e. the call to
> str.__init__ has no effect.
That's correct. Objects of type str are immutable, so by the time
self exists (as it must for __init__), it's too late to change its
value. You want this:
class AlwaysLower(str):
def __new__(cls, value):
return str.__new__(cls, value.lower())
Note that __new__ doesn't take a "self" argument -- in effect, it's
responsible for *creating* "self". Instead it's passed the desired
result class. __new__ *can* return an object of any type, but it's
most useful most often if it honors the request to return an object of
the passed-in class.
Give the above,
>>> a = AlwaysLower('AbC')
>>> type(a)
<class '__main__.AlwaysLower'>
>>> a
'abc'
>>>
> ...
> Anyone know of good examples of how to subclass builtins?
Lib/test/test_descr.py has many examples. I don't get into value
judgments about "good" <wink>.
More information about the Python-list
mailing list