1 The composition of the Python extension module
In Python, this module is typically C for some system-related modules or for modules with high performance requirements. The following sections are mainly included in the extension module:
The init function, which is called the init+ module name, is responsible for initializing the module, including initialization of methods, objects, and other related data in the Setup module. This function is required, and this method is executed first when the module is imported in the script.
Defines a module method description table, which is a static type of PYMETHODDEF data structure used to describe the methods defined in the module.
c function definitions, which are concrete implementations of methods in the method description table.
If a class is defined in a module, the class method description table and object type are also defined.
2 Implementing a Python expansion module instance
Of course, with the above components, you still do not know how to implement a module, the following is an official example to demonstrate how to implement a Python extension module, which is used to implement command-line command in Python.
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
#include PyObject * PyObject * spam_system (pyobject *self, pyobject * * (! Pyarg_parsetuple (args, , & sts = (sts < pyerr_setstring (spamerror, PyMethodDef SpamMethods[] = { {null, null, , NULL} Initspam ( PyObject * m = py_initmodule ( (m = = spamerror = pyerr_newexception ( pymodule_addobject (m, }
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
The above initspam is the initialization function of the module, the function begins to call Py_initmodule Initializes a module named Spam, the module's Method description table is Spammethods, it describes the module has a method called system, this method of C/s The implementation is the Spam_system function. From the Spam_system function, you can see that it is calling the system function to execute commands that come from Python. With the code above, how do we use it in Python? It is very simple to compile the above code into a dynamic-link library, and then import the module directly into Python with the imported statement can be used. With vs compilation under Windows, but after vs has built the DLL project, you need to set the properties of the project to set the header file path and the dynamic library involved in the Python extension. The settings are as follows: Set the Include and LIB paths in the VC + + directory, and then add the Python27.lib Library to the linker's additional dependencies.
650) this.width=650; "Src=" http://images2015.cnblogs.com/blog/407509/201702/407509-20170207163522213-37887328. JPG "width=" 670 "height=" 259 "style=" margin:0px auto;padding:0px;border:none; "/>
650) this.width=650; "Src=" http://images2015.cnblogs.com/blog/407509/201702/407509-20170207163733838-1386727273. PNG "width=" 671 "height=" 233 "style=" margin:0px auto;padding:0px;border:none; "/>
After the setup is ready, the compiler generated DLL file suffix is changed to PYD, and then it can be imported directly into Python using import. is not very simple!!!!
650) this.width=650; "Src=" http://images2015.cnblogs.com/blog/407509/201702/407509-20170207164211276-853301382. PNG "width=" 632 "height=" 510 "style=" margin:0px auto;padding:0px;border:none; "/>
3 Implementing a class defined in the Python extension module
The above implementation is to define functions in the module to implement command-line commands, we can also define the class in the module, and then use the method of the class to execute the command. The code is as follows:
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
#include PyObject * PyObject * spam_system (pyobject *self, pyobject * * (! Pyarg_parsetuple (args, , & sts = (sts < pyerr_setstring (spamerror, PyMethodDef SpamMethods[] = { {null, null, , NULL} PyTypeObject *SpamType = initspam ( pytypeobject _spamtype = , , (Pyobject), , , , , , , , , , , , , , , , , Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE , , , , , , , , spammethods, , , , , , , , , , PyType_GenericNew, PyObject * m = py_initmodule ( (m == (Pytype_ready (&_spamtype) < spamtype = & pymodule_addobject (m, , (PyObject* spamerror = pyerr_newexception ( pymodule_ AddObject (M,&NBSP;&NBSP;}
650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>
The above code is just a spam class definition with the previous code, using the Spam object to invoke the system function.
650) this.width=650; "Src=" http://images2015.cnblogs.com/blog/407509/201702/407509-20170207170415463-645771565. PNG "width=" 653 "height=" 275 "style=" margin:0px auto;padding:0px;border:none; "/>4 python/c API involves reference counting issues
By the above example, is it really easy to write a python C extension module? Actually, there is a reference counting problem in Python, which must be handled very carefully when writing the extension module, otherwise it is easy to cause memory leak. According to the official Python definition, the behavior of the reference count in the PYTHON/C API is summed up in three types: new reference, borrow reference, and steal reference, the first two describing the return pyobject* The behavior of the type's function on the reference count of the returned object, and the latter is the behavior of the function's reference count on the object after passing a pyobject* type into the function. New referenc means that the function transfers the ownership of the object reference to the function caller, which is managed by the caller of the function to manage the imported count, that is, the caller must display the call when the reference is not used.Py_DECREF()或者
Py_xdecref () to release this reference, the typical function isPyObject_、
PyNumber_
、PySequence_和
PyMapping_
Borrow reference is just the opposite of new reference, which means that the caller of the function can use this reference without caring about its reference count, running out of it and not showing the callPy_DECREF()或者
Py_XDECREF()来释放这个引用,典型的函数是PyList_GetItem、PyTuple_GetItem
The steal reference means that only this reference is used inside the function and does not call Py_incref to increase the reference count of the reference, which is equivalent to "stealing" a reference count of the callee, and the typical function isPyList_SetItem()和PyTuple_SetItem()
。 Therefore, when writing a C extension, if you encounter a PYTHON/C API is not sure what kind of reference, it is recommended to check the official documents, the document will clearly explain what kind of reference the function is (as shown), which can greatly reduce the problem of reference counting.
650) this.width=650; "Src=" http://images2015.cnblogs.com/blog/407509/201702/407509-20170207173927010-707066125. PNG "width=" 872 "height=" "style=" margin:0px auto;padding:0px;border:none; "/>
Fast implementation of Python C expansion modules