[Tutor] use of __new__

Steven D'Aprano steve at pearwood.info
Fri Mar 12 02:17:06 CET 2010


On Fri, 12 Mar 2010 11:26:19 am Alan Gauld wrote:
> "spir" <denis.spir at gmail.com> wrote
>
> > The issue is the object (self) is then a unicode one instead of my
> > own type.
>
> I think you need to modify self in __new__

The method signature for __new__ is usually written as:

    def __new__(cls, args):

because when __new__ is called, no instance yet exists. __new__ is the 
constructor method which creates an instance, so it gets the class as 
the first instance.

__new__ can then do one of two things:

(1) return a new instance of your class; or

(2) return something else.

If it returns an instance of your class, Python then automatically calls 
the initializer __init__ with that instance as an argument (plus any 
other arguments passed to __new__).


>>> class MyClass(object):
...     def __new__(cls):
...             print "Calling __new__ on object %s" % cls
...             return super(MyClass, cls).__new__(cls)
...     def __init__(self):
...             print "Calling __init__ on object %s" % self
...
>>> o = MyClass()
Calling __new__ on object <class '__main__.MyClass'>
Calling __init__ on object <__main__.MyClass object at 0xb7c6f44c>
>>> o
<__main__.MyClass object at 0xb7c6f44c>


For mutable types, you can modify self inside __init__, but that doesn't 
work for immutable objects like unicode, str, int, etc. For them, you 
have to do any changes inside __new__ BEFORE creating the instance.

In the second case, where __new__ returns something else, __init__ is 
never called:


>>> class AnotherClass(MyClass):
...     def __new__(cls):
...             ignore = super(AnotherClass, cls).__new__(cls)
...             return 42
...
>>> o = AnotherClass()
Calling __new__ on object <class '__main__.AnotherClass'>
>>> o
42




-- 
Steven D'Aprano


More information about the Tutor mailing list