first, 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:
The code is as follows:
#-*-Coding:utf-8-*-
class Person (object):
"" "Silly Person" ""
def __init__ (self, Name, age):
Self.name = Name
Self.age = Age
def __str__ (self):
Return ' % (Self.name, self.age)
if __name__ = = ' __main__ ':
Piglei = person (' Piglei ', 24)
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.
second, 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.
The code is as follows:
#-*-Coding:utf-8-*-
class Person (object):
"" "Silly Person" ""
Def __new__ (CLS, name, age):
print ' __new__ called. '
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 ', 24)
Print Piglei
Execution Result:
The code is as follows:
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 the main 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__?
Third, 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.
The code is as follows:
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:
The code is as follows:
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.
Iv. 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.
The code is as follows:
Class Singleton (object):
def __new__ (CLS):
# The key is this, every time we instantiate, we'll just return the same instance object.
If not hasattr (CLS, ' instance '):
Cls.instance = Super (Singleton, CLS). __new__ (CLS)
Return cls.instance
Obj1 = Singleton ()
Obj2 = Singleton ()
OBJ1.ATTR1 = ' value1 '
Print Obj1.attr1, OBJ2.ATTR1
Print Obj1 is Obj2
Output Result:
The code is as follows:
Value1 value1
True
You can see that obj1 and Obj2 are the same instance.