python - 如何获取可调用对象的签名参数,或可靠地确定何时这是不可能的?

标签 python python-3.x

内置的int有两个参数:

>>> print(int.__doc__)
int(x=0) -> integer
int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments
...

但是,(在 CPython 3.4.0 中)inspect.signature 显示 0:

>>> len(inspect.signature(int).parameters)
0

与用户定义的函数对比:

>>> def my_int(x, base=10):
...     return int(x, base)
... 
>>> len(inspect.signature(my_int).parameters)
2

docs for inspect.signature说:

Some callables may not be introspectable in certain implementations of Python. For example, in CPython, some built-in functions defined in C provide no metadata about their arguments.

但他们也说:

Raises ValueError if no signature can be provided, and TypeError if that type of object is not supported.

所以令我感到惊讶的是,我没有得到 ValueError,而是得到了一个看起来不正确的签名。

有没有一种方法可以可靠地(以编程方式)确定何时无法使用 inspect 获取可调用对象的参数?也就是说,如果给我类似 int 的东西,有没有办法区分“这个东西没有任何参数”和“无法确定这个东西有哪些参数”?

最佳答案

有一个开放的错误报告:http://bugs.python.org/issue23934

问题是,如果传递给 signature() 的对象是一个“类型”,并且它没有用户定义的 initnew ,它只是放弃并返回 object 的签名,它有 0 个参数。

如果 obj 在内置模块中,并且它是一个“类型”,但不是异常,那么它很可能无法与 signature() 一起使用。

我想出了这个解决方法来找到问题 objs...它不是特别优雅,但它可能对你有用:

def count_params():
    output = {}
    for funcname in dir(builtins):
        f = getattr( builtins,funcname)
        if isinstance(f, type):
            try:
                paramcount = len(inspect.signature(f).parameters)
                output[funcname] = paramcount
            except:
                pass
                #print("%s is a %s" % (funcname, type(f)))
    return output

输出:

{'__loader__': 0,
 'bool': 0,
 'bytes': 0,
 'complex': 0,
 'enumerate': 0,
 'filter': 0,
 'float': 0,
 'frozenset': 0,
 'int': 0,
 'map': 0,
 'memoryview': 0,
 'object': 0,
 'range': 0,
 'reversed': 0,
 'slice': 0,
 'str': 0,
 'tuple': 0,
 'zip': 0}

关于python - 如何获取可调用对象的签名参数,或可靠地确定何时这是不可能的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29477437/

相关文章:

python - 在 python 3.6 上工作但在 3.7.3 上不工作的方法的内存

python - QuerySet,对象没有属性id - Django

python - 使用正则表达式将引号添加到分隔列表

python - 无法从 'parse_version' 导入名称 'sklearn.utils.fixes'

Python OS - 检查文件是否存在,如果存在则重命名,再次检查,然后保存

python - 在python范围内查找素数

python - 编写CSV文件Python3问题

python - 将季度数据框转换为每月数据框并填充每个 ID 的缺失值

python - 如何根据sklearn中的预测概率对实例进行排名

python-3.x - 属性错误: 'module' object has no attribute 'ensure_future'