Type subclassing: bug or feature
Bengt Richter
bokr at oz.net
Thu Jun 13 21:58:14 EDT 2002
On 13 Jun 2002 23:24:09 +0200, Chris Liechti <cliechti at gmx.net> wrote:
>aahz at pythoncraft.com (Aahz) wrote in news:aeau48$111$1 at panix1.panix.com:
>
>> Consider the following code:
>>
>> class MyStr(str):
>> def contains(self, value):
>> return self.find(value) >= 0
>>
>> s = MyStr("hello, world!")
>> s = s.capitalize()
>> if s.contains('Hello'):
>> print "Found it!"
>>
>> It fails with an AttributeError when it calls s.contains(), because
>> s.capitalize() returned a str instead of a MyStr. Anyone want to take a
>> whack at defending this as the correct behavior?
>
>solving this at the C level would require patching many stingobject factory
>functions... e.g. PyString_FromStringAndSize for capitalize(). but it would
>indeed be desireable.
>
>i think it would like to have a even more genral mechanism. i would like to
>have a possibility to replace the builtin type. e.g. i could replace the
>builtin "str" and all strings from now on would be instaces of my class.
>but that's clearly impossible in the current implementation.
>
><hacker warning>
>like Bengt already sugested just automated ;-) ...
>
>>>> class mstr(str):
>... for name,m in str.__dict__.items():
>... if type(m) == type(str.find):
>... exec """def %s(*args, **kwargs):
>... q = str.%s(*args, **kwargs)
>... if type(q) is str: return mstr(q)
>... else: return q\n""" % (name, name)
>... def __contains__(self, other):
>... return str.find(self, other) >= 0
>...
>>>> s = mstr("hello")
>>>> type(s.capitalize())
><class '__main__.mstr'>
>>>> 'll' in s.capitalize()
>1
></hacker warning>
>
Interesting way to go if you can't know except dynamically at run time
what types base class methods will return.
I don't know how you'd fully generalize this process though, and it
seems a shame to have to wrap everything in an extra layer. It would
be nice to be able to specify coercions in the subclass in a way that
base class methods could access quickly to check whether to call a coercion
routine on a result, e.g.,
__coercions__ = (str, mstr), (bool, No_Yes) # just as example with several coercions
Also str.split could even access this, and produce a list of MyStr substrings.
And also deeper bases' methods could check on self.__coercions__
Just OTTOMH, so not very thought through ;-)
BTW, I just thought of a 'where' keyword for 'for' e.g., the above for would become
for name,m in str.__dict__.items() where type(m) == type(str.find):
sort of like sql select ... where ... or the list comprehension if.
Regards,
Bengt Richter
More information about the Python-list
mailing list