What is the __init__ method?
Students who have written object-oriented code in Python may be familiar with the __init__ method, and the __init__ method is often used to initialize a class instance. For example:
#-*-Coding:utf-8-*-class Person (object): "", "" "" "," "" "" def __init__ (self, Name, age): self.name = NA Me self.age = Age def __str__ (self): return '
% (self.name, self.age) if __name__ = = ' __main__ ': Piglei = person (' Piglei ', ') print Piglei
This is the most common usage of __init__. But __init__ is not actually the first method to be called when instantiating a class. When an expression such as persion (name, age) is used to instantiate a class, the first method to be called is actually the __new__ method.
What is the __new__ method?
The __new__ method accepts parameters that are the same as __init__, but __init__ is called after the class instance is created, and the __new__ method is the way to create the class instance.
#-*-Coding:utf-8-*-class Person (object): "", "" "", "" "" "" def __new__ (CLS, name, age): print ' __new__ c alled. ' Return super (person, CLS). __new__ (CLS, name, age) def __init__ (self, Name, age): print ' __init__ called. ' Self.name = name Self.age = Age def __str__ (self): return '
% (self.name, self.age) if __ name__ = = ' __main__ ': piglei = person (' Piglei ', ') print
Piglei
Execution Result:
piglei@macbook-pro:blog$ python new_and_init.py__new__ called.__init__ called.
By running this code, we can see that the invocation of the __new__ method occurred before __init__. In fact, when you instantiate a class, the concrete execution logic is this:
1.P = person (name, age)
2. First execute the __new__ method that uses the name and age parameters to execute the person class, which returns an instance of the person class (typically using super (Persion, CLS). __new__ (CLS, ... ...) Such a way)
3. Then use this example to invoke the __init__ method of the class, the __new__ generated in the previous step is the self within the __init__
So themain difference between __init__ and __new__ is that:
1.__INIT__ is typically used to initialize a new instance, controlling the initialization process, such as adding properties and doing additional operations that occur after the class instance is created. It is an instance-level method.
2.__NEW__ is typically used to control the process of generating a new instance. It is a class-level method.
But when we say so much, what is the most common usage of __new__, and when do we need __new__?
The role of __new__
According to the official Python document, the __new__ method is primarily when you inherit some immutable classes (such as int, str, tuple), providing you with a way to customize the instantiation process for the class. There is also the implementation of custom Metaclass.
First, let's take a look at the first feature, we can use int as an example:
If we need an integer type that is always positive, we might write this code by integrating int.
Class Positiveinteger (int): def __init__ (self, value): super ("Positiveinteger, Self"). __init__ (Self, ABS ( Value)) i = Positiveinteger ( -3) Print I
But after the run we will find that the result is not what we thought, we still got-3. This is because for an immutable object such as int, we only have to reload its __new__ method to be able to customize the function.
This is the modified code:
Class Positiveinteger (int): def __new__ (CLS, value): return Super (Positiveinteger, CLS). __new__ (CLS, ABS ( Value)) i = Positiveinteger ( -3) Print I
By overloading the __new__ method, we implemented the required functionality.
In addition a function, about custom metaclass. In fact, when I first approached __new__, it was because of the need to customize the Metaclass, but for the space reasons, we will talk about Python next time metaclass and __new__ relationship.
Using __new__ to achieve a single case
In fact, when we understand the __new__ method, we can also use it to do some other interesting things, such as implementing a singleton pattern (singleton) in design patterns.
Because the process of every instantiation of a class is controlled by __new__, we can easily implement a singleton mode by overloading the __new__ method.
Class Singleton (object): def __new__ (CLS): # The key is this, every time we instantiate, we will only return this same instance object if not hasattr (CLS, ' Instance '): cls.instance = Super (Singleton, CLS). __new__ (CLS) return cls.instanceobj1 = Singleton () Obj2 = Singleton () obj1.attr1 = ' value1 ' Print obj1.attr1, Obj2.attr1print obj1 is Obj2
Output Result:
Value1 value1
True
You can see that obj1 and Obj2 are the same instance.