Python C API: PyEval_CallFunction?
我发现了一个在Python C API中叫做 PyEval_CallFunction
的函数,感觉这个函数挺有用的。它可以让你通过类似下面的方式来调用Python中的可调用对象:
PyEval_CallFunction(obj, "OOO", a, b, c);
不过,我找不到这个函数的官方文档。用谷歌搜索一下,能找到一些非官方的教程,讨论这个函数,但:
这个函数在官方Python文档中没有记录,所以我不知道它是否应该是公共API的一部分。
在网上搜索时,发现使用这个函数的规则不一致。有些教程说格式字符串需要在类型列表周围加上括号,比如
"(OiiO)"
,而其他时候我看到它没有括号。实际上在我的程序中尝试这个函数时,它似乎需要括号,否则就会出现错误。
我想用这个函数,因为它很方便。有没有人知道这个函数的情况,或者知道为什么没有文档?它是公共API的一部分吗?
2 个回答
之所以没有文档说明,是因为你应该使用 PyObject_CallFunction 这个函数。
PyEval_*
这一系列函数是用来进行解释器评估循环的底层内部调用。与之对应的、已经有文档的 PyObject_*
函数则包含了额外的检查,比如确保解释器的状态是正确的、验证参数是否有效,以及保护调用栈。
我也没找到很多相关的资料,不过你提到的那个教程里有这么一句:
字符串格式和后面的参数跟
Py_BuildValue
是一样的(XXX 所以我应该早就解释这个了!)。像这样的调用:PyEval_CallFunction(obj, "iii", a, b, c);
其实是等同于:
PyEval_CallObject(obj, Py_BuildValue("iii", a, b, c));
我觉得 PyEval_CallFunction
可能不是公开的API,因为它的用途似乎比较有限。这两个之间其实没什么大区别。不过,我自己并没有深入参与Python扩展的开发,所以这只是我个人的看法。
PyEval_CallObject
本身只是一个宏,它是围绕 PyEval_CallObjectWithKeywords
这个函数的。
#define PyEval_CallObject(func,arg) \
PyEval_CallObjectWithKeywords(func, arg, (PyObject *)NULL)
关于“什么是公开API?”这里有马丁·冯·洛维斯的最近一条消息:
我想强调并支持乔治的解释:API并不是通过文档来定义的,而主要是通过头文件来定义的。所有声明为
PyAPI_FUNC
且不以 _Py 开头的函数都是公开API。以前有很多没有文档的API(在1.4之前,根本没有API文档,只有扩展模块的教程);现在,越来越多的API开始有文档了。
http://mail.python.org/pipermail/python-dev/2011-February/107973.html