Python - 进一步扩展:初学者指南

你好,有抱负的Python程序员们!今天,我们将开始一段激动人心的Python扩展世界之旅。如果你是编程新手,也无需担心——我会作为你的友好向导,一步一步地解释一切。那么,让我们开始吧!

Python - Further Extensions

Python扩展是什么?

在开始之前,让我们先了解什么是Python扩展。把Python想象成一把瑞士军刀。它已经相当有用了,但有时候你需要的一个工具并不在其中。这就是扩展的用武之地——它们就像是在你的Python瑞士军刀上添加新工具。

编写扩展的前提条件

我知道你很急切地想要开始,但首先我们需要设置一些东西。这就像是烹饪美食前的厨房准备。以下是您需要的:

  1. 在您的计算机上安装Python
  2. 一个C编译器(比如Linux上的GCC或Windows上的Visual Studio)
  3. Python开发标头和库

如果这听起来很复杂,请不要担心。大多数Python安装都包含了您所需的内容,我会指导您完成任何额外的设置。

第一次接触Python扩展

让我们从一个简单的例子开始。想象一下,我们想要创建一个函数来计算两个数字的和,但我们希望它非常快。我们可以用C语言编写这个函数,然后在Python中使用它。以下是它可能的样子:

#include <Python.h>

static PyObject* add_numbers(PyObject* self, PyObject* args) {
int a, b;
if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
return NULL;
}
return Py_BuildValue("i", a + b);
}

static PyMethodDef MyMethods[] = {
{"add", add_numbers, METH_VARARGS, "Add two numbers."},
{NULL, NULL, 0, NULL}
};

static struct PyModuleDef mymodule = {
PyModuleDef_HEAD_INIT,
"mymodule",
"A simple module that adds numbers",
-1,
MyMethods
};

PyMODINIT_FUNC PyInit_mymodule(void) {
return PyModule_Create(&mymodule);
}

如果现在这看起来像是一碗字母汤,请不要惊慌。我们会一步一步地分解它。

头文件Python.h

我们代码的第一行是:

#include <Python.h>

这就像是在告诉我们的C程序:“嘿,我们在这里将要使用Python!”它包含了我们创建Python扩展所需的所有必要定义和函数。

C函数

接下来,我们有我们的实际C函数:

static PyObject* add_numbers(PyObject* self, PyObject* args) {
int a, b;
if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
return NULL;
}
return Py_BuildValue("i", a + b);
}

这个函数接收两个Python对象作为输入,从中提取两个整数,将它们相加,并返回结果作为Python对象。它就像C和Python之间的翻译器。

方法映射表

static PyMethodDef MyMethods[] = {
{"add", add_numbers, METH_VARARGS, "Add two numbers."},
{NULL, NULL, 0, NULL}
};

这个表就像是我们Python模块的菜单。它告诉Python:“这个模块中有哪些函数可用。”在这个例子中,我们提供了一个名为“add”的函数。

初始化函数

PyMODINIT_FUNC PyInit_mymodule(void) {
return PyModule_Create(&mymodule);
}

当Python导入我们的模块时,会调用这个函数。它就像新店的开业——它设置一切,使我们的模块准备好使用。

构建和安装扩展

现在我们已经编写了扩展,我们需要构建它。这个过程将我们的C代码转换为Python可以使用的东西。这就像烤蛋糕——我们已经混合了配料,现在需要把它放进烤箱。

我们通常会使用一个setup.py文件来完成这个工作:

from distutils.core import setup, Extension

module = Extension('mymodule', sources = ['mymodule.c'])

setup(name = 'MyModule',
version = '1.0',
description = 'This is a demo package',
ext_modules = [module])

要构建扩展,你需要运行:

python setup.py build

导入扩展

一旦构建完成,你可以像使用任何其他Python模块一样使用你的新模块:

import mymodule

result = mymodule.add(5, 3)
print(result)  # 输出:8

是不是很酷?你刚刚在Python中使用了C函数!

传递函数参数

让我们更多地谈谈如何从Python传递参数到C。还记得这一行吗?

if (!PyArg_ParseTuple(args, "ii", &a, &b))

PyArg_ParseTuple函数

这个函数是理解参数如何传递的关键。它就像一个海关官员,检查和处理从Python到我们C函数的所有东西。

函数中的"ii"告诉它期望两个整数。如果你想要传递一个字符串和一个浮点数,你会使用"sf"代替。以下是一个格式说明符的便捷表格:

格式说明符 Python类型 C类型
i int int
l long long
f float float
d float double
s str char*
O 任何对象 PyObject*

返回值

就像我们需要仔细处理传入的数据一样,我们也需要正确地包装我们的返回值。

Py_BuildValue函数

这个函数就像是我们C值的礼物包装器,让Python接收时看起来很漂亮。以下是它的工作原理:

return Py_BuildValue("i", a + b);

"i"告诉Py_BuildValue创建一个整数对象。如果我们想返回一个字符串,我们会使用"s"代替。

就这样!你已经迈出了Python扩展世界的第一步。记住,熟能生巧。尝试编写自己的简单扩展,玩转不同的数据类型,最重要的是,玩得开心!

Python扩展开启了无限可能的新世界,让你能够优化代码的关键部分或与现有的C库接口。这是你编程工具箱中的一个强大工具。

快乐编程,直到下次,继续探索和学习!

Credits: Image by storyset