如何在Python中找出方法的arity

Fed*_*les 30 python metaprogramming

我想找出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
Run Code Online (Sandbox Code Playgroud)

我希望能够做到这一点:

Foo().bar.arity()   # => 1
Run Code Online (Sandbox Code Playgroud)

更新:现在上面的函数失败了内置类型,对此的任何帮助也将受到赞赏:

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

Ale*_*lli 48

inspectPython标准库中的模块是您的朋友 - 请参阅在线文档! inspect.getargspec(func)返回四个选项的元组,args, varargs, varkw, defaults:len(args)是"主元数",但参数数量可以从任何东西到无穷大,如果你有varargs和/或varkw没有None,并且可以省略一些参数(和默认的),如果defaults不是None.你怎么把它变成一个数字,打败了我,但大概你在这个问题上有你的想法! - )

这适用于Python编码的函数,但不适用于C编码的函数.Python C API中没有任何内容允许C编码函数(包括内置函数)公开其内省的签名,除非通过它们的文档字符串(或者可选地通过Python 3中的注释); 所以,如果其他方法失败,你需要回退到docstring解析作为最后一个沟渠(当然,文档字符串可能也会丢失,在这种情况下,函数将仍然是一个谜).

  • 在Python 3.3中,这变成了[`inspect.signature`](https://docs.python.org/3.5/library/inspect.html#introspecting-callables-with-the-signature-object):`from inspect import signature; LEN(签名(a_func).parameters)` (3认同)

Anu*_*yal 6

使用装饰器来装饰方法,例如

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

现在实现_arity函数根据您的需要计算arg计数