在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
http://www.tutorialspoint.com/python/python_further_extensions.htm Any code that you write using any compiled language like C, C++ or Java can be integrated or imported into another Python script. This code is considered as an "extension." A Python extension module is nothing more than a normal C library. On Unix machines, these libraries usually end in .so (for shared object). On Windows machines, you typically see .dll (for dynamically linked library). Pre-Requisite:To start writing your extension, you are going to need the Python header files.
Additionally, it is assumed that you have good knowledge of C or C++ to write any Python Extension using C programming. First look at a Python extension:For your first look at a Python extension module, you'll be grouping your code into four parts:
The header file Python.hStart including Python.h header file in your C source file, which will give you access to the internal Python API used to hook your module into the interpreter. Be sure to include Python.h before any other headers you might need. You'll follow the includes with the functions you want to call from Python. The C functions:The signatures of the C implementations of your functions will always take one of the following three forms: staticPyObject *MyFunction(PyObject*self,PyObject*args );
Each one of the preceding declarations returns a Python object. There's no such thing as a void function in Python as there is in C. If you don't want your functions to return a value, return the C equivalent of Python's None value. The Python headers define a macro, Py_RETURN_NONE, that does this for us. The names of your C functions can be whatever you like as they will never be seen outside of the extension module. So they would be defined as static function. Your C functions usually are named by combining the Python module and function names together, as shown here: staticPyObject*module_func(PyObject*self,PyObject*args){/* Do your stuff here. */Py_RETURN_NONE;} This would be a Python function called func inside of the module module. You'll be putting pointers to your C functions into the method table for the module that usually comes next in your source code. The method mapping table:This method table is a simple array of PyMethodDef structures. That structure looks something like this: structPyMethodDef{char*ml_name;PyCFunction ml_meth;int ml_flags;char*ml_doc;};
Here is the description of the members of this structure:
This table needs to be terminated with a sentinel that consists of NULL and 0 values for the appropriate members. EXAMPLE:For the above-defined function, we would have following method mapping table: staticPyMethodDefmodule_methods[]= The initialization function:The last part of your extension module is the initialization function. This function is called by the Python interpreter when the module is loaded. It's required that the function be named initModule, where Moduleis the name of the module. The initialization function needs to be exported from the library you'll be building. The Python headers define PyMODINIT_FUNC to include the appropriate incantations for that to happen for the particular environment in which we're compiling. All you have to do is use it when defining the function. Your C initialization function generally has the following overall structure: PyMODINIT_FUNC initModule(){Py_InitModule3(func,module_methods,"docstring...");} Here is the description of Py_InitModule3 function:
Putting this all together looks like the following: #include <Python.h> static PyObject *module_func(PyObject *self, PyObject *args) { /* Do your stuff here. */ Py_RETURN_NONE; } static PyMethodDef module_methods[] = { { "func", (PyCFunction)module_func, METH_NOARGS, NULL }, { NULL, NULL, 0, NULL } }; PyMODINIT_FUNC initModule() { Py_InitModule3(func, module_methods, "docstring..."); }
EXAMPLE:A simple example that makes use of all the above concepts:
#include <Python.h> static PyObject* helloworld(PyObject* self) { return Py_BuildValue("s", "Hello, Python extensions!!"); } static char helloworld_docs[] = "helloworld( ): Any message you want to put here!!\n"; static PyMethodDef helloworld_funcs[] = { {"helloworld", (PyCFunction)helloworld, METH_NOARGS, helloworld_docs}, {NULL} }; void inithelloworld(void) { Py_InitModule3("helloworld", helloworld_funcs, "Extension module example!"); }
Here the Py_BuildValue function is used to build a Python value. Save above code in hello.c file. We would see how to compile and install this module to be called from Python script. Building and Installing Extensions:The distutils package makes it very easy to distribute Python modules, both pure Python and extension modules, in a standard way. Modules are distributed in source form and built and installed via a setup script usually called setup.py as follows. For the above module, you would have to prepare following setup.py script: from distutils.core import setup,Extension
setup(name='helloworld', version='1.0', \
ext_modules=[Extension('helloworld',['hello.c'])])
Now, use the following command, which would perform all needed compilation and linking steps, with the right compiler and linker commands and flags, and copies the resulting dynamic library into an appropriate directory: $ python setup.py install On Unix-based systems, you'll most likely need to run this command as root in order to have permissions to write to the site-packages directory. This usually isn't a problem on Windows Import Extensions:Once you installed your extension, you would be able to import and call that extension in your Python script as follows: #!/usr/bin/pythonimport helloworld print helloworld.helloworld() This would produce the following result: Hello,Python extensions!! Passing Function Parameters:Because you'll most likely want to define functions that do accept arguments, you can use one of the other signatures for your C functions. For example, following function, that accepts some number of parameters, would be defined like this: staticPyObject * module_func(PyObject*self,PyObject*args){/* Parse args and do something interesting here. */Py_RETURN_NONE;} The method table containing an entry for the new function would look like this: static PyMethodDef module_methods[]= You can use API PyArg_ParseTuple function to extract the arguments from the one PyObject pointer passed into your C function. The first argument to PyArg_ParseTuple is the args argument. This is the object you'll be parsing. The second argument is a format string describing the arguments as you expect them to appear. Each argument is represented by one or more characters in the format string as follows. static PyObject *module_func(PyObject *self, PyObject *args) { int i; double d; char *s; if (!PyArg_ParseTuple(args, "ids", &i, &d, &s)) { return NULL; } /* Do something interesting here. */ Py_RETURN_NONE; }
Compiling the new version of your module and importing it will enable you to invoke the new function with any number of arguments of any type: module.func(1, s="three", d=2.0)
module.func(i=1, d=2.0, s="three")
You can probably come up with even more variations. The PyArg_ParseTuple Function:Here is the standard signature for PyArg_ParseTuple function: intPyArg_ParseTuple(PyObject* tuple,char* format,...)
This function returns 0 for errors, and a value not equal to 0 for success. tuple is the PyObject* that was the C function's second argument. Here format is a C string that describes mandatory and optional arguments. Here is a list of format codes for PyArg_ParseTuple function:
Returning Values:Py_BuildValue takes in a format string much like PyArg_ParseTuple does. Instead of passing in the addresses of the values you're building, you pass in the actual values. Here's an example showing how to implement an add function: staticPyObject * foo_add(PyObject*self,PyObject*args) This is what it would look like if implemented in Python: def add(a, b):return(a + b) You can return two values from your function as follows, this would be cauptured using a list in Python. staticPyObject * foo_add_subtract(PyObject*self,PyObject*args) This is what it would look like if implemented in Python: def add_subtract(a, b):return(a + b, a - b) The Py_BuildValue Function:Here is the standard signature for Py_BuildValue function: PyObject*Py_BuildValue(char* format,...) Here format is a C string that describes the Python object to build. The following arguments ofPy_BuildValue are C values from which the result is built. The PyObject* result is a new reference. Following table lists the commonly used code strings, of which zero or more are joined into string format.
Code {...} builds dictionaries from an even number of C values, alternately keys and values. For example, Py_BuildValue("{issi}",23,"zig","zag",42) returns a dictionary like Python's {23:'zig','zag':42}.
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论