如何自省Cython C扩展模块中定义的功能 [英] How to introspect a function defined in a Cython C extension module
问题描述
Python的 inspect
模块似乎无法检查内置"功能的签名,其中包括C扩展模块中定义的功能,例如Cython定义的功能.有什么方法可以获取您在此类模块(特别是在Cython中)中定义的Python函数的签名?我希望能够找到可用的关键字参数.
Python's inspect
module doesn't seem to be able to inspect the signatures of "built-in" functions, which include functions defined in C extension modules, like those defined by Cython. Is there any way to get the signature of a Python function you have defined in such a module, and specifically in Cython? I am looking to be able to find the available keyword arguments.
MWE:
# mwe.pyx
def example(a, b=None):
pass
和
import pyximport; pyximport.install()
import mwe
import inspect
inspect.signature(mwe.example)
产量:
Traceback (most recent call last):
File "mwe_py.py", line 5, in <module>
inspect.signature(mwe.example)
File "/nix/store/134l79vxb91w8mhxxkj6kb5llf7dmwpm-python3-3.4.5/lib/python3.4/inspect.py", line 2063, in signature
return _signature_internal(obj)
File "/nix/store/134l79vxb91w8mhxxkj6kb5llf7dmwpm-python3-3.4.5/lib/python3.4/inspect.py", line 1965, in _signature_internal
skip_bound_arg=skip_bound_arg)
File "/nix/store/134l79vxb91w8mhxxkj6kb5llf7dmwpm-python3-3.4.5/lib/python3.4/inspect.py", line 1890, in _signature_from_builtin
raise ValueError("no signature found for builtin {!r}".format(func))
ValueError: no signature found for builtin <built-in function example>
在Python 3.4.5和Cython 0.24.1中
In Python 3.4.5 and Cython 0.24.1
推荐答案
经过进一步调查,我撤回了我的重复建议(说这是不可能的...).在相当近期的Cython(v0.23.4)和Python 3.4.4版本中,它似乎可以正常工作.
I've retracted my duplicate suggestion (saying that it was impossible...) having investigated further. It seems to work fine with reasonably recent versions of Cython (v0.23.4) and Python 3.4.4.
import cython
import inspect
scope = cython.inline("""def f(a,*args,b=False): pass """)
print(inspect.getfullargspec(scope['f']))
提供输出
FullArgSpec(args=['a'], varargs='args', varkw=None, defaults=None, kwonlyargs=['b'], kwonlydefaults={'b': False}, annotations={})
也在>文档中提及"binding
" 显然使此细节更易于访问(尽管我不需要它).
Also mentioned in the documentation is the compilation option "binding
" which apparently makes this detail more accessible (although I didn't need it).
我觉得这可能取决于最近对inspect
所做的改进(可能是此修复程序),因此,如果您使用的是Python 2,则可能不走运.
I have a feeling that this may depend on improvements to inspect
made relatively recently (possibly this fix) so if you're using Python 2 you're probably out of luck.
如果使用binding
编译选项,则您的示例有效:
your example works if you using the binding
compilation option:
import cython
@cython.binding(True)
def example(a, b=None):
pass
我怀疑inline
是自动添加的(但是执行inline
的代码非常复杂,以至于我找不到这两种方式的证明).您也可以将其设置为文件级选项.
I suspect that inline
adds it automatically (but the code to do inline
is sufficiently convoluted that I can't find proof of that either way). You can also set it as a file-level option.
这篇关于如何自省Cython C扩展模块中定义的功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!