converting base class instance to derived class instance

Michele Simionato michele.simionato at poste.it
Wed Jan 21 07:04:03 EST 2004


sridharinfinity at yahoo.com (Sridhar R) wrote in message news:<930ba99a.0401200413.5fae6fb9 at posting.google.com>...
> Consider the code below,
> 
> class Base(object):
>   pass
> 
> class Derived(object):
> 
>   def __new__(cls, *args, **kwds):
>     # some_factory returns an instance of Base
>     # and I have to derive from this instance!
>     inst = some_factory() # this returns instance of Base
>     return inst  # Oops! this isn't an instance of Derived
> 
>   def __init__(self):
>     # This won't be called as __new__ returns Base's instance
>     pass
> 
>   The constrait is there is some factory function that creates an
> instance of Base class.  So I _can't_ call "Base.__init__(self)" in
> Derived.__init__ func, as their will be _two_ instances (one created
> by Derived.__init__ and other created by the factory function)
> 
>   Simply I want to get a derived class object, but instead of allowing
> _automatic_ creation of Base instance, I want to use _existing_ Base's
> instance, then use this as a Derived's instance.
> 
>   Will metaclass solve this problem?

I don't really understand what you want to do (i.e. do you want 
Derived.__init__ to be called or not?). Moreover, as others pointed
out, it is cleaner to use a class factory than to pervert __new__.
If you really want to use a metaclass, you could override the 
__call__ method of the metaclass, in such a way to interfer with the
class instantiation. For instance, this is the code to make a singleton
class (which is a FAQ ;)

class Singleton(type):
    "Instances of this metaclass are singletons"
    def __init__(cls,name,bases,dic):
        super(Singleton,cls).__init__(name,bases,dic)
        cls.instance=None
    def __call__(cls,*args,**kw):
        if cls.instance is None:
            cls.instance=super(Singleton,cls).__call__(*args,**kw)
        return cls.instance

class C:
    __metaclass__=Singleton

This is not what you want but you can play with __call__ and get 
the behavior you want. Still, why don't just use a simple factory?

     Michele Simionato



More information about the Python-list mailing list