什么情况下需要扩展 Python
- 需要 Python 没有的额外功能
- 改善瓶颈性能
- 隐藏专有代码
在 Python 和 C/C++之间转换数据
从 Python 到 C
- int PyArg_ParseTuple() 将位于元组中的一系列参数从 Python 转化为 C
- int PyArg_ParseTupleAndKeywords() 与上一个类似,但还会解析关键字参数
从 C 到 Python
- PyObject*Py_BuildValue() 将 C 数据值转化为 Python 返回对象,要么是单个对象,要么是一个含有多个对象的元组
Python①和 C/C++之间的“转换编码”
- s、 s# str/unicode, len() Char*(, int)
- z、 z# str/unicode/None,len() char*/NULL(, int)
- u、 u# unicode, len() (Py_UNICODE*, int)
- i int int
- b int char
- h int short
- l int long
- k int 或 long unsigned long
- I int 或 long unsigned int
- B int unsigned char
- H int unsigned short
- L long long long
- K long unsigned long long
- c str char
- d float double
- f float float
- D complex Py_Complex*
- O (任意类型) PyObject*
- S str PyStringObject
- N② (任意类型) PyObject*
- O& (任意类型) (任意类型)
static PyObject *
Extest_fac(PyObject *self, PyObject *args) {
int res; // parse result
int num; // arg for fac()
PyObject* retval; // return value
res = PyArg_ParseTuple(args, "i", &num);
if (!res) { // TypeError
return NULL;
}
res = fac(num);
retval = (PyObject*)Py_BuildValue("i", res);
return retval;
}
static PyObject *
Extest_fac(PyObject *self, PyObject *args) {
int num;
if (!PyArg_ParseTuple(args, "i", &num))
return NULL;
return (PyObject*)Py_BuildValue("i", fac(num));
}
static PyObject *
Extest_doppel(PyObject *self, PyObject *args) {
char *orig_str; // original string
char *dupe_str; // reversed string
PyObject* retval;
if (!PyArg_ParseTuple(args, "s", &orig_str)) return NULL;
retval = (PyObject*)Py_BuildValue("ss", orig_str, \
dupe_str=reverse(strdup(orig_str)));
free(dupe_str);
return retval;
}
为模块编写 PyMethodDef ModuleMethods[]数组
static PyMethodDef ExtestMethods[] = {
{ "fac", Extest_fac, METH_VARARGS },
{ "doppel", Extest_doppel, METH_VARARGS },
{ NULL, NULL },
};
添加模块初始化函数 void initModule()
void initExtest() {
Py_InitModule("Extest", ExtestMethods);
}
编译
导入测试
其他扩展工具
- SWIG
- Pyrex
- Cython
- psyco
- PyPy
文档信息
- 本文作者:zhupite
- 本文链接:https://zhupite.com/python/python-c.html
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)