Any gotchas in returning a subclass instance from __new__?

Duncan Booth duncan.booth at invalid.invalid
Tue Aug 1 07:58:50 EDT 2006


 wrote:

> Hi All,
> 
> Is anything wrong with the following code?
> 
> class Superclass(object):
>   def __new__(cls):
>     # Questioning the statement below
>     return super(Superclass, cls).__new__(Subclass)
> class Subclass(Superclass):
>   pass
> if __name__ == '__main__':
>   instance = Superclass()
>   print instance
> 
The only problems I can think if is that if you create any other subclasses 
of Superclass, or of Subclass for that matter then you'll never succeed in 
creating any of them, and the constructor i.e. __new__ of the subclass 
never gets called.

I've used this technique where the Superclass iterates through all of its 
subclasses and uses the constructor parameters to choose the most 
appropriate subclass to construct. Eventually though I changed it to use a 
separate factory function: that way the __new__ methods get called in the 
expected order.

So something like:

    @classmethod
    def fromMimetype(cls, m):
        for subclass in Superclass._handlers():
            if subclass.supportsMimetype(m):
                return subclass(m)

    @classmethod
    def _handlers(cls):
        for c in cls.__subclasses__():
            for sub in c._handlers():
                yield sub
            yield c

> It works here, and even constructors for Subclass and Superclass are
> invoked (in correct order), even though such behavior is not explicitly
> stated here http://docs.python.org/ref/customization.html. So, am I
> asking for trouble or is it /the/ way to go about transforming base
> class into a factory?
> Thank you,
> 
I think you meant the initialisers are invoked correctly (the constructor 
is the __new__ method): this isn't suprising since the system simply calls 
__init__ on the returned object so the correct thing just happens.




More information about the Python-list mailing list