Unpythonic? Impossible??

Scott David Daniels scott.daniels at acm.org
Sun Mar 19 11:54:25 EST 2006


BrJohan wrote:
> Assume having this class hierarchy: (in principle and without details)
>     class A(object):
>     class B1(A):
>     class B2(A):
>     ...
> each of those classes have an initializer __init__(self, data):  and an 
> overloaded __new__(cls, data):
> 
> is it then possible to have this call:
>     obj = A(data)
> return an instance of that particular class (e.g. class C3)  in the 
> hierarchy that - as decided by the __new__ functions - is the 'correct' one?
> 
> A.__new__ could select between A, B1 and B2, while B1.__new__ could choose 
> from B1, C3 and C4.
> 
> I know how to use a class factory - and could work around using such a 
> mechanism. However I am interested to know if I could let the classes do the 
> work by themselves.

Yes, it can be done.  Yes, it is unclear (and hence UnPythonic).
The class factory _is_ the straightforward way to do this.  The
following is the workaround (if you have to maintain A(...)):


     class A(object):
         def __new__(class_, *args, **kwargs):
             if class_ is A:
                 if want_a_B1(*args, **kwargs):
                     return B1(*args, **kwargs)
                 elif want_a_B2(*args, **kwargs):
                     return B2(*args, **kwargs)
             return object.__new__(class_) # Use *a,... except for object

     class B1(A):
         def __new__(class_, *args, **kwargs):
             if class_ is B1:
                 if want_a_B1(*args, **kwargs):
                     return B1(*args, **kwargs)
                 elif want_a_B2(*args, **kwargs):
                     return B2(*args, **kwargs)
             return super(B1, class_).__new__(class_, *args, **kwargs)


--Scott David Daniels
scott.daniels at acm.org



More information about the Python-list mailing list