[Tutor] my __new__ not getting called before __init__

Roeland Rengelink r.b.rigilink@chello.nl
Wed, 26 Dec 2001 13:03:42 +0100


Hi Karthik,

For this to work you must make sure that Singleton is a new style class
by deriving it from object

This works partially:

class HoldThis:
    def __init__(self,arg):
        # note ',' instead of '+' on next line
        print "KeepThis called with ", arg 
        self.val = arg
    def func(self):
        print self.val
        
class Singleton(object):
    __instance=None

    def __init__(self,arg):
        print "Singleton called"
    def __new__(cls,arg):
        print "__new__ called"
        if not Singleton.__instance:
            Singleton.__instance = HoldThis(arg)
        else:
            Singleton.__instance.val = arg
        return Singleton.__instance
    def __getattr__(self,name):
        return getattr(Singleton.__instance,name)
    def __setattr__(self,name,value):
        setattr(Singleton.__instance,name,value)

Singleton(1)
Singleton(1)

It gives the following result:

__new__ called
KeepThis called with  1
__new__ called

HoldThis.__init__ is called because of the line 

Singleton.__instance = HoldThis(arg)

If you also derive HoldThis from 'object' You get the following result:

__new__ called
KeepThis called with  1
KeepThis called with  1
__new__ called
KeepThis called with  1

Which is in line with the descriptor doc (__new__ called before
__init__), although maybe not in the way you might expect
(Holdhis.__init__ is calles, not Singleton.__init__).

Object instantiation (new style) is implemented roughly equivalent to:

def __call__(cls, *args, **kwargs):
    instance = cls.__new__(*args, **kwargs)
    type(instance).__init__(instance, *args, **kwargs)
    return instance

Note that type(HoldThis()) in the classic case is InstanceType, which
has only a default (no-op) __init__ method. In the new style case
type(HoldThis()) is HoldThis

No idea if this works as an explanation. Let me know if you need
additional clarification

Roeland

Karthik Gurumurthy wrote:
> 
> Is something wrong with this code?
> when i run it using python2.2 Singleton's __init__ is getting called
> and not HoldThis's __init__.
> 

That was because Singleton.__new__ was not being called

> http://www.python.org/2.2/descrintro.html
> 
> says the __new__ is always called before __init__.
> 
> thanks,
> karthik.
> 
> <code>
[snip]
> </code>

Roeland 
-- 
r.b.rigilink@chello.nl

"Half of what I say is nonsense. Unfortunately I don't know which half"