【问题标题】:Python call a function with arguments from a tuple which is larger than the amount of arguments neededPython使用元组中的参数调用函数,该元组大于所需的参数数量
【发布时间】:2019-04-02 04:14:05
【问题描述】:

补充说明:

我想要达到的是

call(function,(*args,*toomanyargs)) == (function(*args),*toomanyargs)
call(function_with_varargs,(*args))) == (function_with_varargs(*args))

实现这一点的pythonic方法是什么

【问题讨论】:

  • 您是否将函数作为参数传递?
  • call 将采用 1 个函数和 1 个元组,并将尽可能多的参数传递给函数,并根据结果和未传递给函数的参数创建一个新元组。

标签: python arguments


【解决方案1】:

您可以通过访问.__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,)

【讨论】:

    【解决方案2】:

    一种方法是使用locals() (Check the number of parameters passed in Python function; https://docs.python.org/3/library/functions.html#locals),并在每个函数的主体中进行一些数学运算,以确定剩余的参数数量(未使用)。然后,您可以返回一个包含未使用参数的元组的结果。

    【讨论】:

    • 这仅在函数内部起作用。它不允许您从外部检查参数的数量。
    • 哦,我明白你现在在说什么了。我想我的(澄清的)建议是编写您传递给call() 的函数,以获取所有 *args 并适当地处理它们。
    • 因为call函数想知道function接受了多少参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 1970-01-01
    • 2018-07-03
    • 1970-01-01
    • 1970-01-01
    • 2022-11-28
    • 1970-01-01
    相关资源
    最近更新 更多