如何自省Cython C扩展模块中定义的功能 [英] How to introspect a function defined in a Cython C extension module

查看:181
本文介绍了如何自省Cython C扩展模块中定义的功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆