pythonmetaprogramming

How to find out the arity of a method in Python


I'd like to find out the arity of a method in Python (the number of parameters that it receives). Right now I'm doing this:

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

I'd like to be able to achieve this:

Foo().bar.arity()   # => 1

Update: Right now the above function fails with built-in types, any help on this would also be appreciated:

 # 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

Solution

  • Module inspect from Python's standard library is your friend -- see the online docs!

    In earlier versions of Python, the method of choice was inspect.getargspec(func) , which returns a tuple with four items, args, varargs, varkw, defaults: len(args) is the "primary arity", but arity can be anything from that to infinity if you have varargs and/or varkw not None, and some arguments may be omitted (and defaulted) if defaults is not None. How you turn that into a single number, beats me, but presumably you have your ideas in the matter!-)

    In more recent versions of Python, the inspect.signature method is preferred; a call such as inspect.signature(my_func) returns a Signature object, with a parameters field.

    This applies to Python-coded functions, but not to C-coded ones. Nothing in the Python C API lets C-coded functions (including built-ins) expose their signature for introspection, except via their docstring (or optionally via annotations in Python 3); so, you will need to fall back to docstring parsing as a last ditch if other approaches fail (of course, the docstring might be missing too, in which case the function will remain a mystery).