I am interested in obtaining a general way to obtain a list of arguments and keyword arguments taken by a callable Python object. This is straight-forward for functions with the inspect.getargspec function, for example:
import inspect
from functools import partial
def foo(*args, **kwargs):
return args, kwargs
print(inspect.getargspec(foo))
>>ArgSpec(args=[], varargs='args', keywords='kwargs', defaults=None)
def bar(*args):
return args
print(inspect.getargspec(bar))
>>ArgSpec(args=[], varargs='args', keywords=None, defaults=None)
However, this fails in cases such as these:
partial_function = partial(foo, kwarg="value")
inspect.getargspec(partial_function)
>>TypeError: <functools.partial object at 0x11748bc58> is not a Python function
class Foo(object):
def __call__(self, *args, **kwargs):
return args, kwargs
foo_instance = Foo()
inspect.getargspec(foo_instance)
>>TypeError: <__main__.Foo object at 0x116c13ed0> is not a Python function
inspect.getargspec(zip)
>>TypeError: <built-in function zip> is not a Python function
Note, that there are ways to obtain the arguments for the partial function and for the callable object, i.e:
inspect.getargspec(partial_function.func)
>>ArgSpec(args=[], varargs='args', keywords='kwargs', defaults=None)
inspect.getargspec(foo_instance.__call__)
>>ArgSpec(args=['self'], varargs='args', keywords='kwargs', defaults=None)
but I would like a more general way of obtaining these results, if at all possible.
All these can be handled by using the
inspect.signaturehelper function which, as stated in its docs:What
signaturedoes is it takes your callable and constructs aSignatureobject from it:with the arguments now lying in the
parametersmapping attribute for theSignatureinstance:With a
partialobject, you'd get the corresponding representation:As for built-in functions such as
zip, this isn't always possible, some of these functions don't expose the appropriate metadata to construct a signature, fromPEP 362:So, while
zipisn't the type to expose information about itself, others are, e.gall:you'll unfortunately require a
try-exceptfor these, there's nothing else that can be done.The cases that the
signaturehelper handles are enumerated in the implementation section ofPEP 362which introduced it.In general,
inspect.getargspechas been deprecated for a while now in Python 3, the suggested approach (if you're using Python 3, that is) is to use the representation offered viaSignatureobjects.If on Python
2, I'm pretty sure you can't do it directly withgetargspec, you should usegetfullargspecas Anttis' answer suggests.