Some code that users write by any compiled language like C, C++, or Java can be mixed or imported into one more Python script. This code is believed as an "extension."
A Python extension unit is zilch in excess of a normal C library. On Unix mechanisms, these libraries typically end in .so (for shared objects). On Windows engines, users typically observe .dll (for dynamically linked libraries).
For users first look at a Python extension module, users require to group their code into four-part?
Users require to embrace Python.h header file in your C source file, which presents users access to the inner Python API used to hook your module into the interpreter.
Ensure to comprise Python. h before any additional headers users might require. Users call for to follow with the functions users want to call from Python.
The signatures of the C implementation of your functions always take one of the following three forms
static PyObject *MyFunction( PyObject *self, PyObject *args ); static PyObject *MyFunctionWithKeywords(PyObject *self, PyObject *args, PyObject *kw); static PyObject *MyFunctionWithNoArgs( PyObject *self );
Each one of the previous statements returns a Python object. There is no such obsession as a canceled function in Python as a present is in C. If users do not desire functions to return a value, return the C equivalent of Python's None value. The Python headers describe a macro, Py_RETURN_NONE, that does this for us.
The names of your C functions can be anything users like, as they are never seen the exterior of the extension module. They are described as still function.
UsersC functions characteristically are named by combine the Python module and function names together, as shown here:
static PyObject *module_func(PyObject *self, PyObject *args) { /* Do your stuff here. */ Py_RETURN_NONE; }
This is a Python utility called func in of the module. Users will be putting sticks to their C functions into the technique table for the module that more often than not comes next in users' source code.
This method table is a simple array of PyMethodDef structures. That structure looks something like this
struct PyMethodDef { 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 have the following method mapping table:
static PyMethodDef module_methods[] = { { "func", (PyCFunction)module_func, METH_NOARGS, NULL }, { NULL, NULL, 0, NULL } };
The previous fraction of your extension unit is the initialization function. This function is known by the Python interpreter when the component is loaded. It is involved that the function is named initModule, where Module is the name of the module.
The initialization function requires to be sending abraded from the library you will be building. The Python headers define PyMODINIT_FUNC to include the appropriate incantations for that to happen for the particular environment in which we are 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 the Py_InitModule3 function:
Putting this all together looks like the following:
#include 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..."); }
A simple example that makes use of all the above concepts:
#include 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..."); }
Here the Py_BuildValue function is used to build a Python value. Save the above code in hello.c file. We would see how to compile and install this module to be called from Python script.
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 need to prepare the following setup.py script:
from distutils.core import setup, Extension setup(name='helloworld', version='1.0', \ ext_modules=[Extension('helloworld', ['hello.c'])])
This would produce the following result:
Hello, Python extensions!!
As you will most likely want to define functions that accept arguments, you can use one of the other signatures for your C functions. For example, the following function, that accepts some number of parameters, would be defined like this:
static PyObject *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[] = { { "func", (PyCFunction)module_func, METH_NOARGS, NULL }, { "func", module_func, METH_VARARGS, NULL }, { NULL, NULL, 0, NULL } };
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 will 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 enables 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") module.func(s="three", d=2.0, i=1)
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 ?
Code | C type | Meaning |
---|---|---|
c | char | A Python string of length 1 becomes a C char. |
d | double | A Python float becomes a C double. |
f | float | A Python float becomes a C float. |
i | int | A Python int becomes a C int. |
l | long | A Python int becomes a C long. |
L | long long | A Python int becomes a C long long |
O | PyObject* | Gets a non-NULL borrowed reference to Python argument. |
s | char* | Python string without embedded nulls to C char*. |
s# | char*+int | Any Python string to C address and length. |
t# | char*+int | Read-only single-segment buffer to C address and length. |
u | Py_UNICODE* | Python Unicode without embedded nulls to C. |
u# | Py_UNICODE*+int | Any Python Unicode C address and length. |
w# | char*+int | Read/write single-segment buffer to C address and length. |
z | char* | Like s, also accepts None (sets C char* to NULL). |
z# | char*+int | Like s#, also accepts None (sets C char* to NULL). |
(...) | as per ... | A Python sequence is treated as one argument per item. |
' | The following arguments are optional. | |
: | Format end, followed by function name for error messages. | |
; | Format end, followed by entire error message text. |
Py_BuildValue takes in a format string much like PyArg_ParseTuple does. Instead of passing in the addresses of the values you are building, you pass in the actual values. Here's an example showing how to implement an add function:
static PyObject *foo_add(PyObject *self, PyObject *args) { int a; int b; if (!PyArg_ParseTuple(args, "ii", &a, &b)) { return NULL; } return Py_BuildValue("i", a + b); }
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 captured using a list in Python.
static PyObject *foo_add_subtract(PyObject *self, PyObject *args) { int a; int b; if (!PyArg_ParseTuple(args, "ii", &a, &b)) { return NULL; } return Py_BuildValue("ii", a + b, a - b); }
This is what it would look like if implemented in Python:
def add_subtract(a, b): return (a + b, a - b)
Here is the standard signature for the Py_BuildValue function:
def add_subtract(a, b): return (a + b, a - b)
Here format is a C string that describes the Python object to build. The following arguments of Py_BuildValue are C values from which the result is built. The PyObject* result is a new reference.
The following table lists the commonly used code strings, of which zero or more are joined into the string format.
Code | C type | Meaning |
---|---|---|
c | char | A C char becomes a Python string of length 1. |
d | double | A C double becomes a Python float. |
f | float | A C float becomes a Python float. |
i | int | A C int becomes a Python int. |
l | long | A C long becomes a Python int. |
N | PyObject* | Passes a Python object and steals a reference. |
O | PyObject* | Passes a Python object and INCREFs it as normal. |
O& | convert+void* | Arbitrary conversion |
s | char* | C 0-terminated char* to Python string, or NULL to None. |
s# | char*+int | C char* and length to Python string, or NULL to None. |
u | Py_UNICODE* | C-wide, a null-terminated string to Python Unicode, or NULL to None. |
u# | Py_UNICODE*+int | C-wide string and length to Python Unicode, or NULL to None. |
w# | char*+int | Read/write single-segment buffer to C address and length. |
z | char* | Like s, also accepts None (sets C char* to NULL). |
z# | char*+int | Like s#, also accepts None (sets C char* to NULL). |
(...) | as per ... | Builds Python tuple from C values. |
[...] | as per ... | Builds Python list from C values. |
{...} | as per ... | Builds Python dictionary from C values, alternating keys, and values. |
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}.
Here at Intellinuts, we have created a complete Python tutorial for Beginners to get started in Python.