5

我在名为的 Python C API 中发现了一个PyEval_CallFunction似乎很有用的函数。它允许您通过说以下内容来调用 Python 可调用对象:

PyEval_CallFunction(obj, "OOO", a, b, c);

但是,我找不到有关此功能的任何官方文档。谷歌搜索带来了各种讨论此功能的非官方教程,但是:

  1. 该函数没有记录在官方 Python 文档中,所以我不知道它是否应该是公共 API 的一部分。

  2. 搜索网络会发现不一致的使用政策。一些教程指出格式字符串需要在类型列表周围加上括号,例如 "(OiiO)",而其他时候我看到它在没有括号的情况下使用。当我在实际程序中实际尝试该功能时,它似乎需要括号,否则会出现段错误。

我想使用这个功能,因为它很方便。有谁知道这件事,或者知道为什么没有记录?它是公共 API 的一部分吗?

4

2 回答 2

5

我也找不到很多对它的引用,但是您链接到的教程提到了这一点:

字符串格式和以下参数与 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?” 这是 Martin v. Löwis 最近的一条消息:

只是为了强调和支持 Georg 的解释:API不是通过文档定义的,而是主要通过头文件定义的。所有声明为 PyAPI_FUNC 且不以 _Py 开头的函数都是公共 API。曾经有很多无文档的API(到1.4,根本没有API文档,只有扩展模块教程);如今,越来越多的 API 被记录在案。

http://mail.python.org/pipermail/python-dev/2011-February/107973.html

于 2011-02-07T14:51:20.297 回答
5

未记录的原因是您应该改用PyObject_CallFunction

PyEval_*函数族是解释器评估循环的原始内部调用。相应的记录PyObject_*调用包括所有额外的解释器状态完整性检查、参数验证和堆栈保护。

于 2011-02-08T04:26:48.257 回答