First, Introduction
Python is a powerful, advanced scripting language, it is strong not only in its own function, but also in its good scalability, because of this, Python has begun to be more and more people's favor, and has been successfully applied to all kinds of large-scale software system development process.
Unlike other common scripting languages, Python programmers can use the API provided by the Python language, using C or C + + to extend the functionality of Python, thereby leveraging Python's convenient and flexible syntax and functionality, and gaining access to C or C + + Perform almost the same performance. Slow execution is the common denominator of almost all scripting languages and an important factor to be blamed, and Python has cleverly solved the problem with the organic combination of C, which has greatly expanded the scope of application of scripting languages.
When developing real-world software systems with Python, you often need to use C + + to extend Python. The most common scenario is that there is already a library written in C that requires some of the functionality of the library in the Python language, and can be achieved with the extended functionality provided by Python. In addition, because Python is essentially a scripting language, some features can be difficult to implement in Python to meet the performance requirements of actual software systems, as well as the extended capabilities provided by Python to implement these critical snippets in C or C + + to provide performance for execution of programs.
This article mainly introduces the C language extension interface provided by Python, and how to use these interfaces and C + + language to extend the functionality of Python, supplemented with concrete examples to describe how to implement Python's functional expansion.
Second, Python's C language interface
Python, a scripting language implemented in C, is inherently open and extensible, and provides a convenient and flexible application interface (API) that enables C + + programmers to extend the capabilities of the Python interpreter at all levels. Before you can extend the functionality of Python with C/A + +, you must first master the C language interface provided by the python explanation.
2.1 Python object (Pyobject)
Python is an object-oriented scripting language in which all objects are represented in the Python interpreter as pyobject,pyobject structures that contain all member pointers to Python objects and maintain the Python object's type information and reference count. When you are doing Python's extended programming, once you have to process the Python object in C or C + +, it means maintaining a pyobject structure.
In Python's C language extension interface, most functions have one or more parameters that are pyobject pointer types, and the return values are mostly pyobject pointers.
2.2 Reference Count
To simplify memory management, Python implements automatic garbage collection by referencing the counting mechanism, and each object in Python has a reference count that counts how many times the object is referenced in different locations. Each time a Python object is referenced, the corresponding reference count is incremented by 1, and whenever the Python object is destroyed, the corresponding reference is reduced by 1, and the Python object is actually removed from memory only if the reference count is zero.
The following example illustrates how the Python interpreter uses reference counting to manage Pyhon objects:
Case 1:refcount.py
Class RefCount:
# etc.
R1 = RefCount () # Reference count is 1
r2 = R1 # Reference count is 2
del (R1) # Reference count is 1
del (R2) # Reference count is 0, delete object
Proper maintenance of reference counts is a critical issue when dealing with Python objects in C + +, which can easily result in memory leaks. Python's C language interface provides macros to maintain reference counts, most commonly with py_incref () to increase the reference count of Python objects by 1, and py_decref () to reduce the reference count of Python objects by 1.
2.3 Data Types
Python defines six types of data: integers, floating-point types, strings, tuples, lists, and dictionaries, and when using the C language to expand Python, first learn how to convert between C and Python data types.
2.3.1 integers, floating-point types, and strings
It is relatively simple to use the three data types of integer, floating-point, and string in the C language extension of Python, just know how to build and maintain them. The following example shows how to use Python in the C language for these three types of data:
Case 2:TYPEIFS.C
Build an integer
pyobject* pint = Py_buildvalue ("I", 2003);
Assert (Pyint_check (pint));
int i = Pyint_aslong (pint);
Py_decref (pint);
Build a float
pyobject* pfloat = Py_buildvalue ("f", 3.14f);
ASSERT (Pyfloat_check (pfloat));
float f = pyfloat_asdouble (pfloat);
Py_decref (pfloat);
Build a string
pyobject* pstring = Py_buildvalue ("s", "Python");
ASSERT (Pystring_check (pstring);
int nlen = pystring_size (pstring);
char* s = pystring_asstring (pstring);
Py_decref (pstring);
The tuple in the Python language is a fixed-length array, and all non-keyword (non-keyword) parameters are passed in tuples when the Python interpreter calls methods in the C language extension. The following example demonstrates how to use Python's tuple type in C:
Case 3:TYPETUPLE.C
Create the tuple
pyobject* ptuple = pytuple_new (3);
ASSERT (Pytuple_check (ptuple));
ASSERT (Pytuple_size (ptuple) = = 3);
Set the item
pytuple_setitem (ptuple, 0, Py_buildvalue ("I", 2003));
Pytuple_setitem (ptuple, 1, Py_buildvalue ("F", 3.14f));
Pytuple_setitem (Ptuple, 2, Py_buildvalue ("s", "Python"));
Parse tuple items
int i;
float F;
char *s;
if (! Pyarg_parsetuple (ptuple, "ifs", &i, &f, &s))
pyerr_setstring (pyexc_typeerror, "invalid parameter");
//Cleanup
Py_decref (ptuple);
The list in the Python language is a variable length array, and the list is more flexible than the tuple, using lists to randomly access the Python objects it stores. The following example demonstrates how to use the Python list type in C:
Case 4:TYPELIST.C
Create the list
pyobject* plist = pylist_new (3);//New Reference
assert (Pylist_check (plist));
Set some initial values
for (int i = 0; i < 3; ++i)
Pylist_setitem (plist, I, Py_buildvalue ("I", i));
Insert an item
Pylist_insert (plist, 2, Py_buildvalue ("s", "inserted"));
Append an item
pylist_append (plist, Py_buildvalue ("s", "appended"));
Sort the list
pylist_sort (plist);
Reverse the list
pylist_reverse (plist);
Fetch and manipulate a list slice
pyobject* pslice = Pylist_getslice (plist, 2, 4);//new reference for
(int J = 0; J < Pylist_size (Pslice); ++J) {
Pyobject *pvalue = Pylist_getitem (plist, j);
ASSERT (Pvalue);
}
Py_decref (pslice);
Cleanup
py_decref (plist);
A dictionary in the Python language is a data type that is accessed based on a keyword. The following example demonstrates how to use Python's dictionary type in C:
Case 5:TYPEDIC.C
Create the dictionary
pyobject* pdict = pydict_new ();//New Reference
assert (Pydict_check (pdict));
Add a few named Values
pydict_setitemstring (pdict, "a",
py_buildvalue ("I", 2003));
Pydict_setitemstring (Pdict, "second",
Py_buildvalue ("F", 3.14f));
Enumerate all named values
pyobject* Pkeys = Pydict_keys ();//new reference for
(int i = 0; i < pylist_size (Pkeys); ++i) {
Pyobject *pkey = Pylist_getitem (Pkeys, i);
Pyobject *pvalue = Pydict_getitem (pdict, pkey);
ASSERT (Pvalue);
}
Py_decref (Pkeys);
Remove a named value
pydict_delitemstring (pdict, "second");
Cleanup
py_decref (pdict);
Third, Python's C language extension
3.1 Module Encapsulation
After you know the C language interface of Python, you can use these interfaces provided by the Python interpreter to write the Python C language extension, assuming that you have the following C language function:
Case 6:EXAMPLE.C
int fact (int n)
{
if (n <= 1) return
1;
else return
N * fact (n-1);
}
The function is to compute the factorial of a given natural number, and if you want to call the function in the Python interpreter, you should first implement it as a module in Python, which requires writing the appropriate encapsulation interface, as follows:
Case 7:WRAP.C
#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}< c21/>};
void Initexample ()
{
pyobject* m;
m = Py_initmodule ("Example", Examplemethods);
}
A typical Python extension module should contain at least three parts: the exported function, the list of methods, and the initialization function.
3.2 Export functions
To use a function in the C language in the Python interpreter, first write the corresponding export function for it, the export function in the example above is wrap_fact. In Python's C language extension, all exported functions have the same function prototype:
Pyobject* method (pyobject* self, pyobject* args);
The function is an interface between the Python interpreter and the C function, with two parameters: Self and args. The parameter self is only used when the C function is implemented as an inline method (built-in methods), and the value of the parameter is usually null (NULL). Parameter args contains all the parameters that the Python interpreter passes to the C function, usually using the function pyarg_parsetuple () provided by the Python C language extension interface to obtain these parameter values.
All exported functions return a pyobject pointer, and if the corresponding C function does not have a true return value (that is, the return value type is void), return a global None object (Py_none) and increase its reference count by 1, as follows:
Pyobject* method (Pyobject *self, Pyobject *args)
{
py_incref (py_none);
return py_none;
}
The method list shows all the methods that can be used by the Python interpreter, and the preceding example corresponds to the following list of methods:
Static Pymethoddef examplemethods[] =
{
{"fact", Wrap_fact, Meth_varargs, "Caculate n!"},
{NULL, null}< c13/>};
Each item in the method list consists of four parts: The method name, the exported function, the parameter passing method, and the method description. The method name is the name that is used when the method is invoked from the Python interpreter. The parameter transfer mode specifies the concrete form of the Python pass parameter to the C function, and the two optional ways are Meth_varargs and meth_keywords, where Meth_varargs is the standard form of parameter transfer, It passes arguments between the Python interpreter and the C function through the Python tuple, and, in the Meth_keyword way, the Python interpreter and the C function pass through the Python dictionary type between the two parameters.
3.4 Initialization Functions
All Python extension modules must have an initialization function so that the Python interpreter can initialize the module correctly. The Python interpreter stipulates that all the function names for the initialization function must begin with INIT, plus the name of the module. For module example, the corresponding initialization function is:
void Initexample ()
{
pyobject* m;
m = Py_initmodule ("Example", Examplemethods);
}
When the Python interpreter needs to import the module, it looks for the corresponding initialization function based on the name of the module and, once found, calls the function for the appropriate initialization, and the initialization function Py_initmodule () by invoking the function provided by the Python C language extension interface. To register all the methods that are available in the module to the Python interpreter.
3.5 Compiling Links
To use an extension module written in C in the Python interpreter, you must compile it in the form of a dynamic-link library. The following is an example of Redhat Linux 8.0, which describes how to compile a Python extension module written in C into a dynamic-link library:
[xiaowp@gary code]$ gcc-fpic-c-i/usr/include/python2.2 \-i/usr/lib/python2.2/config
\ example.c
wrapper.c< C3/>[xiaowp@gary code]$ gcc-shared-o example.so example.o wrapper.o
3.6 Introducing the Python interpreter
When you build a dynamic-link library of the Python extension module, you can use the extension module in the Python interpreter, and as with the Python self-contained module, the extension module is also introduced with the Import command, as follows:
[xiaowp@gary code]$ python
python 2.2.1 (#1, Aug 2002, 12:15:30)
[GCC 3.2 20020822 (Red Hat Linux Rawhide 3.2-4 ] on linux2
Type ' help ', ' copyright ', ' credits ' or ' license ' for the more information.
>>> Import Example
>>> example.fact (4)
>>>
Iv. concluding remarks
As a powerful scripting language, Python will be more widely used in various fields. To overcome the slow pace of scripting language execution, Python provides the corresponding C-language extension interface, which is implemented in C language by the key code that affects execution performance, and can greatly improve the speed at which scripts are written in Python to meet actual needs.