我试图弄清楚如何使用inspect
:
import inspect
import operator
inspect.signature(operator.add)
然而我收到以下错误:
Traceback (most recent call last):
File "D:\ProgramFiles\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2881, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-82-c98d0a3485c3>", line 1, in <module>
inspect.signature(operator.__add__)
File "D:\ProgramFiles\Anaconda3\lib\inspect.py", line 3002, in signature
return Signature.from_callable(obj, follow_wrapped=follow_wrapped)
File "D:\ProgramFiles\Anaconda3\lib\inspect.py", line 2752, in from_callable
follow_wrapper_chains=follow_wrapped)
File "D:\ProgramFiles\Anaconda3\lib\inspect.py", line 2231, in _signature_from_callable
skip_bound_arg=skip_bound_arg)
File "D:\ProgramFiles\Anaconda3\lib\inspect.py", line 2061, in _signature_from_builtin
raise ValueError("no signature found for builtin {!r}".format(func))
ValueError: no signature found for builtin <built-in function add>
我在这个here上发现了一个类似的线程,但是很久以前这个问题已被标记为重复,并声明他们希望能够为C函数提供一个签名定义,允许该帖子中指定的行为,返回3.4之前。非重复页面为here。但是,尽管如此,从3.6.1开始,看起来有些C函数仍然不是inspectable。然而,这对operator.add()没有多大意义,因为它似乎不应该委托给C函数,即使它确实如此,也是以前签名行为的用例之前提到的python bug报告(所以它让我感到困惑的是为什么我不能将inspect.signature
用于operator.add。
我没有寻找args到函数的1:1映射,这根本不适用于我的设置,它不仅包含运算符函数或内置函数,而是任何函数。我也知道我可以将函数包装在另一个函数中,但是在一般情况下,这意味着对于每个具有此问题的函数,我需要为inspect.signature()
创建一个个人包装器才能工作。我想知道我上面描述的内容是否可行/最小的解决方法(比如一个通用的包装器,其中包装器的签名将匹配它在参数数量方面包含的函数的签名),如果没有,为什么不呢。
答案 0 :(得分:2)
然而,这对operator.add()没有多大意义,因为它似乎不应该委托给C函数
看起来current dev branch已将_operator
模块更改为使用Argument Clinic而不是3.6及更早版本中基于宏的实现,因此inspect.signature
可能适用于3.7。然而,在那之前,你很少有内省。
答案 1 :(得分:0)
我对此感到有些惭愧。但等待3.7不是一种选择。它很好用。当然这是一个野蛮的黑客。
import re
def argnum(op):
try:
op()
except TypeError as e:
msg = e.args[0]
if 'argument' in msg:
match = re.search(R'(\d+)(?!\sgiven)', e.args[0])
if match: return int(match.group(1))
elif 'one' in msg: return 1
raise e
else:
return 0