[Tutor] my __new__ not getting called before __init__

Karthik Gurumurthy karthikg@aztec.soft.net
Wed, 26 Dec 2001 19:19:34 +0530


yep it helped! thanks for sending in the code for the way instantiation
works!
i need to admit this group is so helpful!

karthik.

-----Original Message-----
From: roeland@param.aztec.soft.net
[mailto:roeland@param.aztec.soft.net]On Behalf Of Roeland Rengelink
Sent: Wednesday, December 26, 2001 5:34 PM
To: Karthik Gurumurthy
Cc: tutor@python.org
Subject: Re: [Tutor] my __new__ not getting called before __init__


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"