The previous article introduced the Python enumeration type of standard library, in addition to considering its usefulness, there is an important reason is that its implementation process is a very good learning, understanding the Python class and meta-class examples. So the next two articles take this as an example, digging deeper into the mechanics behind classes and meta-classes in Python.
Open any Python tutorial, you can see the following two words in a certain location:
Python is all object (everything in Python was an object);
Python is a language for object-oriented programming (objects oriented programming, OOP).
Although the meaning of objects may be slightly different in the context of the above two sentences, it is certain that the object has a very important meaning in Python and is the basis for all the content that we will discuss next. So, what exactly is the object?
Objects (object)
Objects are an abstraction of data in Python, and all data in a Python program is represented by the relationship between objects or objects. [Ref:data Model]
By translating object into an "object", RTHK can be seen as a box with data, except that there are other useful attribute information besides pure data, in Python all objects have ID, type, value three attributes:
+---------------+| || Python Object | | | +------+--------+| ID | |+---------------+| Type | |+---------------+| value| |+---------------+
Where the ID represents the memory address, can be viewed through the built-in function ID () , and type represents the category of the object, different categories mean the properties and methods that the object owns, and can be viewed through the type () method:
Object as the basic unit in Python and can be created, named, or deleted. Python generally does not need to manually delete objects, its garbage collection mechanism will automatically handle the objects that are no longer used, of course, if necessary, you can also use the DEL statement to delete a variable, the so-called refers to the object is labeled with a name tag, easy to use, that is, declaring or assigning variables; Next we'll focus on how to create an object. For some python built-in types of objects, you can often use specific syntax to generate, such as numbers directly using Arabic numerals literal, string using quotation marks ', list using [], dictionary using {}, function using DEF syntax, etc., these objects are built in Python, So can we create other types of objects?
Classes and instances
Since Python is an object-oriented programming language, it allows users to create objects themselves, often using class statements, unlike other objects, where class-defined objects (called classes) can be used to produce new objects (called instances):
In the example above, a is a new class we created, and by calling a () we can get an instance object of type A, which we assign to a, which means that we have successfully created an object A that is different from all built-in object types, which is of type __main__. a! so far we can divide all the objects in Python into two categories:
A class that can be used to generate new objects, including built-in int, STR, and a defined by itself;
The instance objects generated by the class, including numbers of built-in types, strings, and their own defined types are __main__. A of a.
There is no problem with simply conceptually understanding the two objects, but here are some of the details that have to be considered in practice:
Some convenient mechanisms are needed to realize the inheritance and overloading in object-oriented programming.
There is a need for a fixed process that allows us to perform certain operations during the generation of instantiated objects;
These two problems are mainly about the special operations of the class, that is, the main content behind this article. If you look back at the first two words, you might think that since the class itself is also an object, how are they generated? This is the problem that will be discussed in the latter article: the class that is used to generate the class object, the meta-Class (Metaclass).
Super, MRO ()
0x00 The last one mentioned in the Zen of Python, the namespace (namespace) is a great idea, and a class or object takes on a part of the namespace in Python. For example, if certain methods or properties have only specific types of objects, the properties and methods of different types of objects may have the same name, but their values might be completely different because they belong to different namespaces. When implementing attributes such as inheritance and overloading of classes, it is also necessary to consider namespaces, taking the implementation of enum types as an example, we need to ensure that the property names of enumerated objects cannot be duplicated, so we need to inherit the built-in Dict class:
Class _enumdict (dict): def __init__ (self): dict.__init__ (self) self._member_names = [] def keys: keys = dict.ke Ys (self) return list (filter (lambda k:k.isupper (), keys) ed = _enumdict () ed[' red '] = 1 ed[' red '] = 2 print (ed, ed.k Eys ()) {' Red ': 1, ' Red ': 2} [' Red ']
In the above example, _enumdict overloads call the parent class Dict Some methods, the above syntax is not wrong, but if we want to change the _enumdict of the parent class, is no longer inherited from Dict, You must manually modify the invocation form of dict.method (self) in all methods, which is not a good practice scenario. To solve this problem, Python provides a built-in function super ():
Print (super.__doc__) super ()-Same as Super (__class__,) super (type) unbound Super Object Super (type, obj)- > Bound Super object; Requires Isinstance (obj, type) super (type, type2), bound Super object; Requires Issubclass (type2, type) Typical use-call a cooperative superclass Method:class C (B): def-meth (self, arg): Super (). Meth (ARG) This works for class methods Too:class C (B): @classmethod def cmeth (CLS, ARG): Super (). Cmeth (ARG)
I initially just took super () as a pointer to the parent class object, but in fact it can provide more functionality: given an object and its subclasses (where the object requires at least a class object, and the subclass can be an instance object), search for the corresponding method from the namespace of the parent class of the object.
Take the following code as an example:
Of course, we can also use the super () method externally, but not in the form of default parameters, because __class__ and self are no longer present in the outer namespace :
Super (d, D). Method () # calling d ' s Parent's method with instance D 4542787992 C.method
The above example can be used to describe:
+----------+| A |+----------+| Method () <---------------+ Super (b,self) +----------+ | | +----------+ +----------+| B | | D |+----------+ super (c,self) +----------+| Method () <---------------+ method () |+----------+ +----------+ |+----------+ | | C | | +----------+ | super (D,self) | method () <---------------+ +----------+
It can be thought that the super () method has found the starting point for the variable search by backtracking to the parent class direction, but how is the order of the backtracking determined? The inheritance relationship in the above example is object->a->b->c->d the order, if it is more complex inheritance relationship?
Class A (object): Pass Class B (a): Def method (self): print ("B-S Method") class C (a): Def method (self): print ("C ' s Me Thod ") class D (B, C): Def __init__ (self): Super (). Method () class E (C, B): def-__init__ (self): Super (). Method () D () e = e () B ' s method C ' s method
Python provides a class method MRO () can specify the order of the search, MRO is the abbreviation for method Resolution order , it is a class approach rather than an instance method, can be overloaded with MRO () method to change the order of the methods in the inheritance, but this needs to be done in the meta-class, here only to see the results:
D.mro () [__main__. D, __main__. B, __main__. C, __main__. A, Object] E.mro () [__main__. E, __main__. C, __main__. B, __main__. A, Object] The super () method is to look up the starting point in the order given by the MRO (): Super (d, D). Method () Super (E, E). Method () B ' s method C's Method Super ( C, E). Method () Super (b, D). Method () B ' s method C ' s method