Can __new__ prevent __init__ from being called?

Felix Wiemann Felix.Wiemann at gmx.net
Tue Feb 15 17:57:12 EST 2005


Steven Bethard wrote:

> Felix Wiemann wrote:
>
>> How can I prevent __init__ from being called on the
>> already-initialized object?
>
> The short answer: you can't:
>      http://www.python.org/2.2.3/descrintro.html#__new__

What a pity.  By the way, I'm just seeing that the web page says:

| If you return an existing object, the constructor call will still call
| its __init__ method. If you return an object of a different class, its
| __init__ method will be called.

However, the latter doesn't seem to be true, or am I missing something?

>>> class A(object):
...   def __init__(self):
...     print 'Init of A.'
... 
>>> instance = A()
Init of A.
>>> class B(object):
...   def __new__(self):
...     return instance
...   def __init__(self):
...     print 'Init of B.'
... 
>>> B()  # <--------- A's __init__ is *not* called.
<__main__.A object at 0x4062424c>
>>> instance = object.__new__(B)
>>> B()  # <--------- B's __init__ is called
Init of B.
<__main__.B object at 0x406243ec>

So there seems to be some type-checking in type.__call__.

> Note that in the Singleton example there, subclasses are told to
> override init, not __init__ for exactly this reason.

I see.

> py> class C(object):
> ...     class __metaclass__(type):
> ...         def __call__(cls, *args, **kwargs):
> ...             if cls.instance is None:
> ...                 print 'Creating instance'
> ...                 cls.instance = cls.__new__(cls, *args, **kwargs)
> ...                 print 'Created'
> ...                 cls.instance.__init__(*args, **kwargs)
> ...             return cls.instance

I didn't think of inlining the metaclass; that's really nice.

> [...] where all the work is done in the metaclass and you don't even
> define __new__.

Yeah, that's good.  I think I'll go that way.

Thanks a lot!

-- 
Felix Wiemann -- http://www.ososo.de/



More information about the Python-list mailing list