Python - 进一步扩展:初学者指南
你好,有抱负的Python程序员们!今天,我们将开始一段激动人心的Python扩展世界之旅。如果你是编程新手,也无需担心——我会作为你的友好向导,一步一步地解释一切。那么,让我们开始吧!
Python扩展是什么?
在开始之前,让我们先了解什么是Python扩展。把Python想象成一把瑞士军刀。它已经相当有用了,但有时候你需要的一个工具并不在其中。这就是扩展的用武之地——它们就像是在你的Python瑞士军刀上添加新工具。
编写扩展的前提条件
我知道你很急切地想要开始,但首先我们需要设置一些东西。这就像是烹饪美食前的厨房准备。以下是您需要的:
- 在您的计算机上安装Python
- 一个C编译器(比如Linux上的GCC或Windows上的Visual Studio)
- 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