如何内省Cython C扩展模块中定义的函数

Gil*_*lly 5 python introspection cython python-c-extension

Python的inspect模块似乎无法检查"内置"函数的签名,其中包括C扩展模块中定义的函数,如Cython定义的函数.有没有办法获得你在这样一个模块中定义的Python函数的签名,特别是在Cython中?我希望能够找到可用的关键字参数.

MWE:

# mwe.pyx
def example(a, b=None):                                                                                                                                                       
    pass       
Run Code Online (Sandbox Code Playgroud)

import pyximport; pyximport.install()                                                                                                                                         
import mwe                                                                                                                                                                    
import inspect                                                                                                                                                                

inspect.signature(mwe.example)   
Run Code Online (Sandbox Code Playgroud)

收益率:

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>    
Run Code Online (Sandbox Code Playgroud)

在Python 3.4.5和Cython 0.24.1中

Dav*_*idW 6

我已经撤回了我的重复建议(说这是不可能的......)进一步调查.它似乎与最新版本的Cython(v0.23.4)和Python 3.4.4一起工作正常.

import cython
import inspect
scope = cython.inline("""def f(a,*args,b=False): pass """)
print(inspect.getfullargspec(scope['f']))
Run Code Online (Sandbox Code Playgroud)

给出输出

FullArgSpec(args=['a'], varargs='args', varkw=None, defaults=None, kwonlyargs=['b'], kwonlydefaults={'b': False}, annotations={})


文档中binding还提到了编译选项" ",它显然使这个细节更容易访问(尽管我不需要它).


我有一种感觉,这可能取决于inspect最近的改进(可能是这个修复),所以如果你使用Python 2,你可能会运气不好.


编辑:如果您使用binding编译选项,您的示例将起作用:

import cython
@cython.binding(True)
def example(a, b=None):                                                                                                                                                       
    pass
Run Code Online (Sandbox Code Playgroud)

我怀疑是inline自动添加它(但是要做的代码inline是完全错综复杂的,我无法找到相应的证据).您也可以将其设置为文件级选项.

  • 谢谢大卫,我已经用 MWE 更新了问题,与内联函数相比,似乎不适用于导入。 (2认同)
  • “getfullargspec”和“signature”似乎无法正确获取“cdef”类方法的关键字参数,尽管它们可以获取“pyx”模块函数的关键字参数。关键字参数看起来就像位置参数一样。这些函数确实可以正确获取模块函数的参数名称。 (2认同)
  • @IoannisFilippidis 我正想告诉你,可能值得填补一个错误,但看起来你已经这样做了...... (2认同)