Revealing the Python Object System and the python System
Guido uses C language to create Python. In the Python world, everything is an object.
1. Python objects in the C perspective
Let's trace back to the source, Python is implemented by the C language, and provides the c api http://docs.python.org/c-api/index.html.
When we think about the problem, it may be easy to understand the object, but the computer can only understand the byte sequence such as the 0, 1 series. Basically, the objects in our computer language are only 0, 1 sequences in a memory space in the memory. These continuous or non-continuous memory spaces can be considered as a whole at a higher level. in Python, the general objects we mentioned are a piece of memory space applied by the struct in C on Heap.
To implement the Python object-oriented Mechanism in C language, you need to define some struct to operate the memory space of those objects.
1. PyObject & PyVarObject
All Python objects share something in common. We can abstract them into a structure PyObject.
C code
- Typedef struct _ object {
- PyObject_HEAD
- } PyObject;
- // In fact, the macro PyObject_HEAD is
- Int ob_refcnt;
- Struct _ typeobject * ob_type;
Ob_refcnt is the object reference count. It exists to implement Python's reference-based garbage collection mechanism.
Another is a pointer to a struct of the type object to represent the type of the object.
In the C language implementation, there is also a struct extended to PyObject
That isPyVarObject, whose content is the macro PyObject_VAR_HEAD, which has an ob_size greater than PyObject to indicate the length of the object. For details, see the http://docs.python.org/c-api/structures.html.
Another point is to avoid obfuscation. Here, PyObject and PyVarObject have no correspondence with real objects in the Python world. These two are only an abstraction of all Python objects in the C language representation. that is to say, in C language, as long as it is the data of a Python object struct, the initial part of its memory will have several variables of the struct above, therefore, a pointer to a PyObject can point to all structures in C that represent Python objects. In this way, in the implementation of C, we can use this unified pointer to operate all the built-in Python object structs.
2. PyTypeObject
Another thing I haven't mentioned just now is the structure of _ typeobject (PyTypeObject), which is the abstraction of all types of objects in Python, in this way, we can use the PyTypeObject pointer to call all types of object structures at the C language level.
C code
- Typedef struct _ typeobject {
- // Note that the start part is PyObject_VAR_HEAD.
- PyObject_VAR_HEAD
- Char * tp_name;/* For printing, in format
- "<Module>. <name> "*/
- Int tp_basicsize, tp_itemsize;/* For allocation */
- /* Methods to implement standard operations */
- Destructor tp_dealloc;
- Printfunc tp_print;
- ......
- /* More standard operations (here
- Binary compatibility )*/
- Hashfunc tp_hash;
- Ternaryfunc tp_call;
- ......
- } PyTypeObject;
3. Correspondence between Python built-in objects and C struct
Now, the object and type abstraction of the Python object-oriented mechanism have been mentioned. Next, let's take a look at how the actually existing objects in python are implemented in C language?
The first thing to talk about is the built-in Python objects, which are defined in C language. After the Python environment is initialized, these objects are created.
C code
- PyAPI_DATA (PyTypeObject) PyType_Type;/* built-in 'type '*/
- PyAPI_DATA (PyTypeObject) PyBaseObject_Type;/* built-in 'object '*/
The object is a basic object in Python. Its structure in C language is PyBaseObject_Type. From the name in C language, we can probably know that this class is a type object.
In Python, <type 'type'> corresponds to PyType_Type in C.
C code
- PyTypeObject PyType_Type = {
- PyObject_HEAD_INIT (& PyType_Type)
- 0,/* ob_size */
- "Type",/* tp_name */
- Sizeof (PyHeapTypeObject),/* tp_basicsize */
- Sizeof (PyMemberDef),/* tp_itemsize */
- ......
- };
Let's take a look at the specific integer.
The struct of an integer instance in C is py1_bject.
C code
- Typedef struct {
- PyObject_HEAD
- Long ob_ival;
- } Py1_bject;
That is to say, with this struct, we can point to the Python integer object in the C language runtime.
Then the corresponding Python Integer type object is
C code
- YTypeObject PyInt_Type = {
- PyObject_HEAD_INIT (& PyType_Type)
- 0,
- "Int ",
- Sizeof (pyequalbject ),
- ......
- };
4. Custom object
When we create a Python object, it is ultimately implemented through the underlying Python layer,
After we define A class A by using the Python language, Python first creates A class Object (class Object) Like A according to the code you write ), then, when you need to create an instance of A, in fact, the underlying Python is actually created through the Class Object.
Ii. Object System from the Python perspective
In a simple Python world, everything is an object. These objects can be divided into three types,
Metaclasses, classes, instance
Classes can be divided into built-in type and user-defined class.
The following is a detailed description of the image.
Note:
The definition of C is as follows (python inherits from a class and is directly written in parentheses after the class name ):
Python code
- Class C (object ):
- ......
The solid line indicates the is-kind-of relationship, and the dotted line indicates the is-instance-of relationship.
When you view the base class of the current classes object (the instances object does not have the _ bases _ attribute), you can use classes_name. _ bases _. The value is a Tuple (Python supports multi-inheritance ).
The method for viewing the type of the current object is object_name. _ class __
We can use some tests to confirm the above figure:
Class with type of all classes
Postscript:
After reading the relevant chapter of "Python source code parsing", I feel that the author is not very organized or his own thinking is not keeping up with the author's thinking. So I want to spend my spare time sorting out my own ways of thinking.
The entry language of your computer is the C language, so it is easy to write.
How does one determine whether an object is an instance of a class in python?
You can use isinstance (s, myclass) to determine
If s is an instance of mycalss, True is returned; otherwise, False is returned.
How to parse Python object parameters
The extension module written in C language must be compiled into a dynamic link library in a Python object. The PyArg_ParseTuple () function provided by the Python C Language extension interface is usually used () to obtain these parameter values. I hope this article will help you. Python is a scripting language implemented in C language. It has excellent openness and scalability and provides convenient and flexible application interfaces (APIS ). This allows C/C ++ programmers to expand the functions of the Python interpreter at various levels. Before using C/C ++ to Expand functions of Python, you must first understand the C language interface provided by the Python interpretation. Python is an object-oriented scripting language. All objects are expressed as PyObject In the Python interpreter. The PyObject structure contains all member pointers of Python objects. Maintain the type information and reference count of Python objects. During Python extension programming, once Python objects must be processed in C or C ++, A PyObject structure should be maintained. In Python C Language extension interfaces, most functions have one or more parameters of the PyObject pointer type, and most of the returned values are PyObject pointers. To simplify memory management, Python uses the reference counting mechanism to implement automatic garbage collection. Each object in Python has a reference count. It is used to count the number of times the object is referenced in different places. Every time a Python object is referenced, the corresponding reference count increases by 1. Every time a Python object is destroyed, the corresponding reference is reduced by 1. Only when the reference count is zero, to delete Python objects from the memory. The following example shows how the Python interpreter manages the Pyhon object using reference count: # include <Python. h> PyObject * wrap_fact (PyObject * self, PyObject * args) {int n, result; if (! PyArg_ParseTuple (args, "I: fact", & n) return NULL; result = fact (n); return Py_BuildValue ("I", result );} static PyMethodDef exampleMethods [] = {"fact", wrap_fact, METH_VARARGS, "Caculate N! "},{ NULL, NULL }}; void initexample () {PyObject * m; m = Py_InitModule (" example ", exampleMethods );} when processing Python objects in C/C ++, correct maintenance of the reference count is a key issue. If it is not handled properly, memory leakage may occur. Python's C language interface provides some macros to maintain the reference count. The most common is to use Py_INCREF () to increase the reference count of Python objects by 1, and use Py_DECREF () to reduce the reference count of Python objects by 1. This function is an interface between the Python interpreter and the C function. It has two parameters: self and args. The self parameter is used only when the C function is implemented as an inline method (built-in method. Generally, the value of this parameter is NULL. The args parameter contains all the parameters that the Python interpreter will pass to the C function, the PyArg_ParseTuple () function provided by the Python C Language extension interface is usually used to obtain these parameter values. Each item in the method list is composed of four parts: method name, export function, parameter transfer method, and method description ....... Remaining full text>