如何将C方法附加到现有的Python类?


我们目前正在编写Python代码,其中使用了C方法。所有库(例如NumPy、OpenCV、PyTorch等)的基础都是用C和C++构建的,即这些库内部调用编译后的C代码,代码将在机器上执行,结果将返回到Python包装器中。

为什么我们在Python中使用C方法?

我们在Python中使用C方法的原因是性能。由于动态类型,Python的性能会下降。

  • 在解释器执行操作之前,它必须减少要传递的操作数的类型。这些类型的操作会影响程序的执行时间。

  • C模块允许我们检查这些操作数并直接通过Python执行机器代码。

  • 要使用C模块,我们必须将其与Python链接。将C模块与Python链接有多种方法。

  • 一种方法是使用CPython API。要了解CPython API的工作原理和用法,使用此API的过程如下。

在Python中使用C API的过程

以下是使用Python中C API的步骤:

首先,我们必须安装python3-dev包才能在Python中使用C方法。可以使用以下代码安装该包。

pip install cpython

使用该代码后,我们必须创建一个名为extension的目录,并在该目录中创建一个扩展名为**extension.c**的文件。假设该文件名为**greet.c**,现在在这个文件中包含以下描述的头文件。

#include <python.h>
#include <string.h>

CPython库将提供**python.h**头文件,还提供许多扩展函数和类型。这个库帮助我们集成Python和C。

示例

现在,让我们创建一个程序来使用CPython库。以下是可以用来使用CPython库的代码。

static PyObject* name(PyObject *self, PyObject* args){
   char *name;
   char greeting[255] = "Hello ";
   if (!PyArg_ParseTuple(args, "s", &name)){
      return NULL;
   }
   strcat(greeting, name);
   return Py_BuildValue("s", greeting);
}

在上面的代码中,我们使用了PyObject。PyObject是在C中表示的Python实例。此PyObject函数有两个参数self和args。

  • self指示当前对象/模块

  • args用于指示Python参数。

定义我们的C方法

**PyArg_ParseTuple**传递到Python中,用于解释C值。第二个参数中的s是一个字符串值。如果是任何其他类型,它将在Python中抛出类型错误。**Py_BuildValue**与**PyArg_ParseTuple**相反。这意味着它从C解释Python中的值。

定义我们的C方法后,我们必须将其与Python接口。以下代码用于与Python进行解释。

static PyMethodDef moduleMethods[] = {
   {"name", name, METH_VARARGS, "Greets with your name"}
};

现在,在将我们的C方法与Python接口之后,我们必须定义模块类型。以下代码可用于定义模块类型。

static struct PyModuleDef greetModule = {
   PyModuleDef_HEAD_INIT,
   "greet",
   "Greetings Module",
   -1,
   moduleMethods
};
PyMODINIT_FUNC PyInit_greet(void){
   return PyModule_Create(&greetModule);
};

在当前程序中导入方法

现在,在定义方法类型并创建方法后,我们必须将其导入到我们的Python环境中。

import greet
print("Name: ", greet.__name__)
print("Docstring: ", greet.__doc__)
print("Greeting: ", greet.name("Lezwon"))

如果我们执行上述代码,将会收到nomodulefound错误。这是因为该模块尚未与Python链接。因此,必须完成以下设置才能在Python中使用用C语言创建的模块。

setuptools

首先,我们必须在Python环境中安装setuptools。必须使用以下代码。

pip install setuptools

现在,我们必须使用Python扩展创建setup文件。以下代码将用于该Python文件中。

from setuptools import setup, Extension
ext_modules = [
   Extension('greet', sources = ['greetmodule.c']),
]
setup(
   name = 'Greeting Project',
   ext_modules = ext_modules
)

在上面的代码中,我们使用了greet。这表示我们在C中创建的模块。要编译我们的代码,我们必须使用以下命令。

python setup.py build_ext --inplace

现在我们可以运行以下代码。

import greet
print("Name: ", greet.__name__)
print("Docstring: ", greet.__doc__)
print("Greeting: ", greet.name("Lezwon"))

更新于:2023年5月15日

浏览量:175

启动您的职业生涯

完成课程获得认证

开始
广告