Re: Can __new__ prevent __init__ from being called?

From: Felix Wiemann (Felix.Wiemann_at_gmx.net)
Date: 02/15/05


Date: Tue, 15 Feb 2005 23:57:12 +0100

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/


Relevant Pages

  • Re: What about a series type?
    ... On 6/7/07, Robert Dober wrote: ... > def initialize ... > @init = init ... puts s1.get_some ...
    (comp.lang.ruby)
  • Re: What about a series type?
    ... def initialize ... @init = init ... puts s1.get_some ...
    (comp.lang.ruby)
  • Re: Creating new types and invoking super
    ... def _init: ... return _init ... This kind of approach can't work, you need to call super(A, obj). ... -- Guilherme H. Polo Goncalves ...
    (comp.lang.python)
  • Re: main window in tkinter app
    ... It might have hit me if the fault was related to someting in baseclass.__initnot taking place, but the recursion loop didn't give me a clue. ... Any idea why failing to init the base class caused the loop? ... var=1 def __init__: pass def getval: return self.var ... As you'd logically expect, if you don't define a function in a derived class but call it ), it will call the method from the base class. ...
    (comp.lang.python)
  • Creating new types and invoking super
    ... let me show some sample codes so I can explain: ... def _init: ... return _init ... It works if A is a direct subclass of object, if it is not I have to ...
    (comp.lang.python)