How to find out the arity of a method in Python

Federico Builes picture Federico Builes · Jun 13, 2009 · Viewed 8.5k times · Source

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

Answer

Alex Martelli picture Alex Martelli · Jun 13, 2009

Module inspect from Python's standard library is your friend -- see the online docs! inspect.getargspec(func) 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!-)

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).