On Sat, 25 Dec 2010 15:58:35 +0000, Duncan Booth wrote: > kj <no.em...@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__, ... > This is reasonable behaviour as for builtin classes performance is more > important than fully implementing polymorphism. If you want to subclass > a builtin class you need to be aware of this and override the behaviour > where it matters. Yes, but I think builtins could probably afford one extra identity check. Something like this: # Pseudocode if type(self) is builtin type: do exactly what is done now else: do something slower, but kinder for superclasses For all I know, the slower branch might be something as simple as calling the C equivalent of type(self)(arg). -- Steven -- http://mail.python.org/mailman/listinfo/python-list