type(d) != type(d.copy()) when type(d).issubclass(dict)
John O'Hagan
research at johnohagan.com
Sat Dec 25 21:40:16 EST 2010
On Sat, 25 Dec 2010, Steven D'Aprano wrote:
> On Sat, 25 Dec 2010 15:58:35 +0000, Duncan Booth wrote:
> > kj <no.email at please.post> wrote:
> >> Watch this:
> >>>>> class neodict(dict): pass
> >>
> >> ...
> >>
> >>>>> d = neodict()
> >>>>> type(d)
> >>
> >><class '__main__.neodict'>
> >>
> >>>>> type(d.copy())
> >>
> >><type 'dict'>
> >>
> >> Bug? Feature? Genius beyond the grasp of schlubs like me?
> >
> > Feature.
>
> I'd say it is neither, and call it a bloody nuisance that nevertheless
> has some justification.
>
> > In (almost?) all cases any objects constructed by a subclass of a
> > builtin class will be of the original builtin class. So, for example,
> > subclass a string and concatenating your subclassed objects still
> > produces a string.
>
> Yes, and the consequence is that any serious subclass must overload every
> method which returns a new instance, otherwise your new subclass doesn't
> "stick" -- you find it being replaced by the builtin as soon as you start
> doing something useful with it.
>
> This is especially a nuisance for subclasses of (say) float, where you
> end up writing heaps of boilerplate like this:
>
> class MyFloat(float):
> def __add__(self, other):
> return self.__class__(super(MyFloat, self).__add__(other))
> # and the same for __mul__, __sub__, __rsub__, __pow__, ...
[...]
I've occasionally wished I could just:
import builtin_subclass_fixer
class MyList(list):
def __init__(self):
builtin_subclass_fixer.fix(self)
...
...
to automatically ensure that new objects returned by MyList methods are of the
same class without my having to identify and override every such method.
IMO one of the benefits of subclassing is that you can just "bolt on"
additional behaviour without having to know all the inner workings of the
superclass, a benefit that is somewhat defeated by this behaviour of builtins.
OTOH - not that I advocate nuisance as a deterrent - the nuisance factor of
this has encouraged me to look harder for simpler solutions. Most of the time
I've realised I didn't really need to subclass at all, and thus avoided "lazy
subclassing".
John
More information about the Python-list
mailing list