getargspec()function that returns the argument specification of a function. However, it only works on functions and methods, not any other python callable. It turns out that there is no way to get the argument specification for built-in callables, but we can implement a version of
getargspec()that can get the specification for classes and callable objects:
import inspectThis version returns exactly the same argument specification tuple as inspect's
"""Get the names and default values of a callable's
A tuple of four things is returned: (args, varargs,
- args is a list of the argument names (it may
contain nested lists).
- varargs and varkw are the names of the * and
** arguments or None.
- defaults is a tuple of default argument values
or None if there are no default arguments; if
this tuple has n elements, they correspond to
the last n elements listed in args.
Unlike inspect.getargspec(), can return argument
specification for functions, methods, callable
objects, and classes. Does not support builtin
functions or methods.
if not callable(obj):
raise TypeError, "%s is not callable" % type(obj)
elif hasattr(obj, 'im_func'):
# For methods or classmethods drop the first
# argument from the returned list because
# python supplies that automatically for us.
# Note that this differs from what
# inspect.getargspec() returns for methods.
# NB: We use im_func so we work with
# instancemethod objects also.
spec = list(inspect.getargspec(obj.im_func))
spec = spec[1:]
elif isinstance(obj, object) and \
not isinstance(obj, type(arglist.__get__)):
# We already know the instance is callable,
# so it must have a __call__ method defined.
# Return the arguments it expects.
# If a nested call to our own getargspec()
# raises NotImplementedError, re-raise the
# exception with the real object type to make
# the error message more meaningful (the caller
# only knows what they passed us; they shouldn't
# care what aspect(s) of that object we actually
raise NotImplementedError, \
"do not know how to get argument list for %s" % \
getargspec()does with one notable exception: if called on a method, the argument list returned in the first tuple element will not include the implicit 'self' argument. The reason is that python implicitly supplies that argument so the caller does not pass it explicitly. I find it more useful to only return the argument specification as seen by callers. If you need a drop-in replacement for
inspect.getargspec(), then you will need to slightly modify the method/classmethod case to not remove the first element in the argument list.