如何将 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 的目录,并在该目录中创建一个扩展名为 .c 的文件。假设文件名为 greet.c,现在在这个文件中包含以下描述的头文件。

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

CPython 库将提供 python.h 头文件,并提供 many.py 扩展函数和类型。此库帮助我们将 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_buildvaluePyArg_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 次浏览

开启你的 职业生涯

通过完成课程获得认证

开始学习
广告