【发布时间】:2018-05-25 22:05:14
【问题描述】:
在我的应用程序中嵌入 Python 并编写扩展类型时,我可以使用正确制作的 .tp_doc 字符串将 signature 添加到方法中。
static PyMethodDef Answer_methods[] = {
{ "ultimate", (PyCFunction)Answer_ultimate, METH_VARARGS,
"ultimate(self, question='Life, the universe, everything!')\n"
"--\n"
"\n"
"Return the ultimate answer to the given question." },
{ NULL }
};
当help(Answer)执行时,返回如下(略):
class Answer(builtins.object)
|
| ultimate(self, question='Life, the universe, everything!')
| Return the ultimate answer to the given question.
这很好,但我使用的是 Python3.6,它支持注释。我想将问题注释为字符串,以及返回 int 的函数。我试过了:
static PyMethodDef Answer_methods[] = {
{ "ultimate", (PyCFunction)Answer_is_ultimate, METH_VARARGS,
"ultimate(self, question:str='Life, the universe, everything!') -> int\n"
"--\n"
"\n"
"Return the ultimate answer to the given question." },
{ NULL }
};
但这会恢复为(...) 表示法,文档变为:
| ultimate(...)
| ultimate(self, question:str='Life, the universe, everything!') -> int
| --
|
| Return the ultimate answer to the given question.
并要求inspect.signature(Answer.ultimate) 会导致异常。
Traceback (most recent call last):
File "<string>", line 11, in <module>
File "inspect.py", line 3037, in signature
File "inspect.py", line 2787, in from_callable
File "inspect.py", line 2266, in _signature_from_callable
File "inspect.py", line 2090, in _signature_from_builtin
ValueError: no signature found for builtin <built-in method ultimate of example.Answer object at 0x000002179F3A11B0>
我尝试在事后使用 Python 代码添加注释:
example.Answer.ultimate.__annotations__ = {'return': bool}
但是内置方法描述符不能以这种方式添加注释。
Traceback (most recent call last):
File "<string>", line 2, in <module>
AttributeError: 'method_descriptor' object has no attribute '__annotations__'
有没有办法使用 C-API 为扩展方法添加注释?
Argument Clinic 看起来很有希望并且可能仍然非常有用,但从 3.6.5 开始,它doesn't support annotations。
annotation
此参数的注释值。目前不支持,因为 PEP 8 要求 Python 库不能使用注释。
【问题讨论】:
-
首先,您能否切换到使用Argument Clinic(或者使用更高级的语言,如 C++ 或 Rust,它们具有很好的包装器,可以更轻松地为您生成所有样板文件)?
-
我相信如果你手动完成这一切,你不能在
PyMethodDef中以声明方式进行,你必须构造函数然后调用PyFunction_SetAnnotations或类似的东西结果,但老实说,我只会将原始 C API 用于添加注释会过大的琐碎事情,所以我不知道。 -
@abarnert 我将不得不寻找那些 C++ 包装器。这是一个 C++ 项目,我切换到用于 python C-API 的 C 文件,所以我可以在声明
PyTypeObjects 时使用{ .tp_doc = "..." }命名结构初始化器语法。 (捂脸)除了 Argument Clinic,我也会调查PyFunction_SetAnnotations。谢谢。
标签: python python-3.6 signature python-c-api python-internals