如何查找Python中方法的参数个数
我想知道在Python中一个方法的参数个数,也就是它能接收多少个参数。
def arity(obj, method):
return getattr(obj.__class__, method).func_code.co_argcount - 1 # remove self
class Foo:
def bar(self, bla):
pass
arity(Foo(), "bar") # => 1
我希望能够做到这个:
Foo().bar.arity() # => 1
更新: 现在上面的函数在处理内置类型时会出错,关于这方面的帮助也很感谢:
# Traceback (most recent call last):
# File "bla.py", line 10, in <module>
# print arity('foo', 'split') # =>
# File "bla.py", line 3, in arity
# return getattr(obj.__class__, method).func_code.co_argcount - 1 # remove self
# AttributeError: 'method_descriptor' object has no attribute 'func_co
5 个回答
这是我能想到的唯一一种方法,可以100%有效地判断一个函数的(最小)参数数量(至少对于用户自定义的函数或用C语言写的函数来说)。不过,你要确保这个函数不会产生任何副作用,也不会抛出类型错误:
from functools import partial
def arity(func):
pfunc = func
i = 0
while True:
try:
pfunc()
except TypeError:
pfunc = partial(pfunc, '')
i += 1
else:
return i
def foo(x, y, z):
pass
def varfoo(*args):
pass
class klass(object):
def klassfoo(self):
pass
print arity(foo)
print arity(varfoo)
x = klass()
print arity(x.klassfoo)
# output
# 3
# 0
# 0
如你所见,这个方法可以确定一个函数的最小参数数量,尤其是当函数接受可变数量的参数时。它也不会考虑类或实例方法中的self或cls参数。
说实话,我不会在生产环境中使用这个函数,除非我确切知道会调用哪些函数,因为这样容易出错。这可能会让这个方法失去意义。
使用装饰器来装饰方法,比如:
def arity(method):
def _arity():
return method.func_code.co_argcount - 1 # remove self
method.arity = _arity
return method
class Foo:
@arity
def bar(self, bla):
pass
print Foo().bar.arity()
现在实现一个 _arity
函数,用来根据你的需求计算参数的数量。
Python标准库中的inspect
模块是你的好帮手——可以查看在线文档!使用inspect.getargspec(func)
可以得到一个包含四个部分的元组,分别是args, varargs, varkw, defaults
:len(args)
表示“主要参数个数”,但如果你有varargs
和/或varkw
不为None
,那么参数个数可以是从这个数到无穷大。而且,如果defaults
不为None
,某些参数可能会被省略(并使用默认值)。至于怎么把这些信息变成一个单一的数字,我就不太清楚了,但你可能有自己的想法!-)
这个方法适用于用Python写的函数,但不适用于用C写的函数。Python的C API并没有提供让C写的函数(包括内置函数)展示它们的参数信息,除了通过它们的文档字符串(或者在Python 3中可以选择使用注解);所以,如果其他方法都不行,你必须依赖文档字符串解析作为最后的手段(当然,文档字符串可能也不存在,这样的话这个函数就成了个谜)。