Determining the number of parameters in a lambda
I am wondering if there is a way to determine (given a variable containing a lambda) the number of parameters the lambda it contains. The reason being, I wish to call a function conditionally dependent on the number of parameters.
What I'm looking for
def magic_lambda_parameter_counting_function(lambda_function):
"""Returns the number of parameters in lambda_function
Args:
lambda_function - A lambda of unknown number of parameters
"""
So I can do something like
def my_method(lambda_function):
# ...
# (say I have variables i and element)
parameter_count = magic_lambda_parameter_counting_function(lambda_function)
if parameter_count == 1:
lambda_function(i)
elif parameter_count == 2:
lambda_function(i, element)
Solution 1:
Lambdas are functions like any other. The argument count is stored in func.__code__.co_argcount
.
>>> foo = lambda x, y=2: x+y
>>> foo.__code__.co_argcount
2
>>> foo = lambda x, y=2, z=3: x+y+z
>>> foo.__code__.co_argcount
3
Solution 2:
I'm skipping the part about how to count the arguments, because I don't know how you want to consider varargs and keywords. But this should get you started.
>>> import inspect
>>> foo = lambda x, y, z: x + y + z
>>> inspect.getargspec(foo)
ArgSpec(args=['x', 'y', 'z'], varargs=None, keywords=None, defaults=None)
It sounds like inspect.getargspec is deprecated as of Python 3 (thanks to @JeffHeaton). The recommend solution uses inspect.signature. The .parameters
member of the result contains a variety of structures depending on the arrangement of parameters to the function in question, but I'm matching my function from the Python 2 example above.
>>> import inspect
>>> foo = lambda x, y, z: x + y + z
>>> inspect.signature(foo).parameters
mappingproxy(OrderedDict([('x', <Parameter "x">), ('y', <Parameter "y">), ('z', <Parameter "z">)]))
Solution 3:
From the documentation on callable types, the func_code
attribute of functions contains a code object, and from the inspect module documentation on code objects there is a co_argcount
member that contains the number of arguments (not including *
or **
args).
So the best way to get this information from a lambda function (or any function) is to use func.func_code.co_argcount
:
>>> foo = lambda a, b, *args, **kwargs: None
>>> foo.func_code.co_argcount
2