Why is __init__() always called after __new__()?
I'm just trying to streamline one of my classes and have introduced some functionality in the same style as the flyweight design pattern.
However, I'm a bit confused as to why __init__
is always called after __new__
. I wasn't expecting this. Can anyone tell me why this is happening and how I can implement this functionality otherwise? (Apart from putting the implementation into the __new__
which feels quite hacky.)
Here's an example:
class A(object):
_dict = dict()
def __new__(cls):
if 'key' in A._dict:
print "EXISTS"
return A._dict['key']
else:
print "NEW"
return super(A, cls).__new__(cls)
def __init__(self):
print "INIT"
A._dict['key'] = self
print ""
a1 = A()
a2 = A()
a3 = A()
Outputs:
NEW
INIT
EXISTS
INIT
EXISTS
INIT
Why?
Use
__new__
when you need to control the creation of a new instance.
Use
__init__
when you need to control initialization of a new instance.
__new__
is the first step of instance creation. It's called first, and is responsible for returning a new instance of your class.
In contrast,
__init__
doesn't return anything; it's only responsible for initializing the instance after it's been created.In general, you shouldn't need to override
__new__
unless you're subclassing an immutable type like str, int, unicode or tuple.
From April 2008 post: When to use __new__
vs. __init__
? on mail.python.org.
You should consider that what you are trying to do is usually done with a Factory and that's the best way to do it. Using __new__
is not a good clean solution so please consider the usage of a factory. Here's a good example: ActiveState Fᴀᴄᴛᴏʀʏ ᴘᴀᴛᴛᴇʀɴ Recipe.
__new__
is static class method, while __init__
is instance method.
__new__
has to create the instance first, so __init__
can initialize it. Note that __init__
takes self
as parameter. Until you create instance there is no self
.
Now, I gather, that you're trying to implement singleton pattern in Python. There are a few ways to do that.
Also, as of Python 2.6, you can use class decorators.
def singleton(cls):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance
@singleton
class MyClass:
...
In most well-known OO languages, an expression like SomeClass(arg1, arg2)
will allocate a new instance, initialise the instance's attributes, and then return it.
In most well-known OO languages, the "initialise the instance's attributes" part can be customised for each class by defining a constructor, which is basically just a block of code that operates on the new instance (using the arguments provided to the constructor expression) to set up whatever initial conditions are desired. In Python, this corresponds to the class' __init__
method.
Python's __new__
is nothing more and nothing less than similar per-class customisation of the "allocate a new instance" part. This of course allows you to do unusual things such as returning an existing instance rather than allocating a new one. So in Python, we shouldn't really think of this part as necessarily involving allocation; all that we require is that __new__
comes up with a suitable instance from somewhere.
But it's still only half of the job, and there's no way for the Python system to know that sometimes you want to run the other half of the job (__init__
) afterwards and sometimes you don't. If you want that behavior, you have to say so explicitly.
Often, you can refactor so you only need __new__
, or so you don't need __new__
, or so that __init__
behaves differently on an already-initialised object. But if you really want to, Python does actually allow you to redefine "the job", so that SomeClass(arg1, arg2)
doesn't necessarily call __new__
followed by __init__
. To do this, you need to create a metaclass, and define its __call__
method.
A metaclass is just the class of a class. And a class' __call__
method controls what happens when you call instances of the class. So a metaclass' __call__
method controls what happens when you call a class; i.e. it allows you to redefine the instance-creation mechanism from start to finish. This is the level at which you can most elegantly implement a completely non-standard instance creation process such as the singleton pattern. In fact, with less than 10 lines of code you can implement a Singleton
metaclass that then doesn't even require you to futz with __new__
at all, and can turn any otherwise-normal class into a singleton by simply adding __metaclass__ = Singleton
!
class Singleton(type):
def __init__(self, *args, **kwargs):
super(Singleton, self).__init__(*args, **kwargs)
self.__instance = None
def __call__(self, *args, **kwargs):
if self.__instance is None:
self.__instance = super(Singleton, self).__call__(*args, **kwargs)
return self.__instance
However this is probably deeper magic than is really warranted for this situation!
To quote the documentation:
Typical implementations create a new instance of the class by invoking the superclass's __new__() method using "super(currentclass, cls).__new__(cls[, ...])"with appropriate arguments and then modifying the newly-created instance as necessary before returning it.
...
If __new__() does not return an instance of cls, then the new instance's __init__() method will not be invoked.
__new__() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation.
I realize that this question is quite old but I had a similar issue. The following did what I wanted:
class Agent(object):
_agents = dict()
def __new__(cls, *p):
number = p[0]
if not number in cls._agents:
cls._agents[number] = object.__new__(cls)
return cls._agents[number]
def __init__(self, number):
self.number = number
def __eq__(self, rhs):
return self.number == rhs.number
Agent("a") is Agent("a") == True
I used this page as a resource http://infohost.nmt.edu/tcc/help/pubs/python/web/new-new-method.html