Get ready
In Python, everything is the object.
Since everything is the object, then the class is also the object, which we call the class object . Here's a simple example (all of the cases in this article are running in Python3.4):
class foo (): Pass Print (ID (foo)) Print (Type (foo)) # Results: # 46627056 # <class ' type ' >
If you want to get a deeper look, you can read: a deep understanding of the meta-class in Python (Metaclass)
Introduced
Recently in reading Tornado source code, found in its source code there are many classes are like this:
class Httpserver (TCPServer, Configurable, Httputil. httpserverconnectiondelegate): def__init__(self, *args, * *Kwargs) : # Ignore args to __init__, real initialization belongsin # Initialize since we ' re C Onfigurable. This means that the default __init__ initialization method is not working, and the Initialize method is changed to initialize the pass
Or simply no __init__, just write a initialize method to replace.
So the heart is wondering, how does tornado do this?
Business
Let's take a look at how the Python interpreter creates the object.
You might be familiar with the __init__ method in Python, and think of it as the first method to invoke when instantiating a class. But he's not really. The first method called when instantiating is actually the __new__ method.
Okay, here's the point:
1 when we instantiate a Class A object , the first call in Python is the __new__ method of the Class A object, and if the Class A object does not have a __new__ method defined, go to the parent class and look in turn until the object class
2 The object class has a __new__ method that takes a parameter (typically a class object), instantiates the argument, and returns an object
3 The Python interpreter will call the __new__ method and pass the Class A object as the first argument, and finally return an object (this object is an instance object of Class A, which we call A1)
The 4 Python interpreter invokes the __init__ method of the A1 object by default and passes the arguments in.
Here's an example to verify:
classASD (object):def __new__(CLS, *args, * *Kwargs):Print('asd.__new__ () is running. CLS ID is%s'%ID (CLS)) R= Super (ASD,CLS).__new__(CLS)Print('r_id is%s'%ID (r))returnRclassbnm (ASD):def __init__(self,name):Print('bnm.__init__ () is running, self ID is%s'%ID (self)) Self.name=namePrint('Bnm.name is%s'%(self.name))Print('asd_id is%s'%ID (ASD))Print('bnm_id is%s'%ID (BNM)) O1= BNM ('ni')Print('o1_id is', ID (o1))#asd_id is 49838320#bnm_id is 49838768#asd.__new__ () is running. CLS ID is 49838768#r_id is 49848400#bnm.__init__ () is running, self ID is 49848400#Bnm.name is NI#o1_id is 49848400
Note: BNM and CLS are the same object! R and O1 are also the same object!
Application
Imitation Tornado implements the initialization method of a custom class:
classASD (object):def __new__(CLS, *args, * *Kwargs): R= Super (ASD,CLS).__new__(CLS) r.initialize (*args)returnRclassbnm (ASD):defInitialize (self):Print('Bnm_initialize is running')classfoo (ASD):defInitialize (self,name): Self.name=namePrint('Foo_initialize is running, my name is%s'%(Self.name)) R=bnm () R1= Foo ('Linghuchong')#Bnm_initialize is running#Foo_initialize is running, my name is LinghuchongView Code
When defining a class, as long as you inherit the ASD class, you will use the Initialize method as the initialization method, do you Feel (WU) Cool (LUN) dazzle (Yong)?
A case-in-depth __new__ and __init__ in Python