__new__ v __init__ - python constructor alternatives?
Archive - Originally posted on "The Horse's Mouth" - 2007-04-14 07:20:47 - Graham Ellis
The constructor you'll normally override (and call when you create an object) in Python is called __init__, but there is also a method called __new__ available to the class author.
If __new__ is defined on a class, it is called in preference to __init__
With __new__ you return the object you have constructed, whereas with __init__ there is an implicit return of the object in the current class.
Here's a code sample showing three classes with a mixture of different constructors.
40:~/ndfi grahamellis$ python newvinit
five
C.__init__ () {}
<__main__.C object at 0x6fc10>
=====================
one
A.__new__ () {}
<__main__.B object at 0x6fc10>
=====================
three
<class '__main__.B'>
<class '__main__.B'>
B.__new__ () {}
four
B.__init__ () {}
<__main__.B object at 0x6fc10>
40:~/ndfi grahamellis$
In class C, there's only an __init__ so that's run. Class A has both, and so the __new__ take precedence. In class B, the __new__ takes precendence but it makes an apparent recursive call that's been diverted to __init__ as something of a safeguard - for illustrative purposes, this one!
When would you use __new__?
1. When you want you constructor to return an object of a different type to the class in which it is defined. For example, you have a class "animal" with subclasses "farmanimal" and "pet" and you want the animal cosntructor to be able to examine the data passed in to it and return an animal ... OR a farmanimal OR a pet depending on that data.
2. It has been suggested that experienced base class programmers override __new__ to discourage programmers who subclass them from overwriting their constructors. Personally, I would suggest that a good training course is better than this form of security through obscurity.