您可以通过访问.__code__.co_argcount 属性了解一个函数接受多少个位置参数:
>>> function = lambda a, b, c: a+b+c
>>> function.__code__.co_argcount
3
但是,这不尊重可变参数:
>>> function = lambda *a: a
>>> function.__code__.co_argcount
0
所以更健壮的解决方案是使用inspect.signature:
import inspect
def call(function, args):
# count the positional arguments
params = inspect.signature(function).parameters.values()
if any(param.kind == inspect.Parameter.VAR_POSITIONAL for param in params):
arg_count = len(args)
else:
POSITIONAL_KINDS = {inspect.Parameter.POSITIONAL_ONLY,
inspect.Parameter.POSITIONAL_OR_KEYWORD}
arg_count = sum(1 for param in params if param.kind in POSITIONAL_KINDS)
# take as many arguments as the function accepts
remainder = args[arg_count:]
args = args[:arg_count]
return (function(*args),) + tuple(remainder)
演示:
>>> function = lambda a, b, c: a+b+c
>>> args = range(5)
>>> call(function, args))
(3, 3, 4)
>>>
>>> function = lambda a, b, c, *d: a+b+c
>>> args = range(5)
>>> call(function, args))
(3,)