如何将关键字参数作为参数传递给函数?

Posted

技术标签:

【中文标题】如何将关键字参数作为参数传递给函数?【英文标题】:How can I pass keyword arguments as parameters to a function? 【发布时间】:2017-08-01 03:27:22 【问题描述】:

假设我有一个这样定义的函数:

def inner_func(spam, eggs):
    # code

然后我想调用这样的函数:

outer_func(spam=45, eggs="blah")

outer_func 内部,我希望能够使用传递给outer_func 的完全相同的参数调用inner_func

这可以通过像这样写outer_func来实现:

def outer_func(spam, eggs):
    inner_func(spam, eggs)

但是,我希望能够更改 inner_func 采用的参数,并相应地更改我传递给 outer_func 的参数,但不必每次都更改 outer_func 中的任何内容。

有没有(简单的)方法可以做到这一点?请使用 Python 3。

【问题讨论】:

我不确定我明白你想要做什么。似乎您希望func_one 调用func_two,有时您需要相同的参数,有时您需要不同的参数。这是模糊的。你能提供一个你想要的功能的例子吗? 当你说“不改变outer_func的定义”时,你的意思是每次改变inner_func都不改变它,还是你的意思是定义仍然应该说def outer_func(spam, eggs):完成后现在的情况如何? @user2357112 我的意思是第一个选项 【参考方案1】:

不完全确定我明白你的意思,但你可能会觉得 functools.wraps 很有趣:

@functools.wraps(inner_func)
def outer_func(*args, **kwds):
    return inner_func(*args, **kwds)

inspect.signature(outer_func)
# <Signature (spam, eggs)>

解释:“星形参数”收集所有未明确指定的后置 (*args) 和关键字 (**kwds) 参数。它们也可以用来传递这些参数;或操纵它们:args 是一个元组,kwds 是一个字典。

由于例如参数spam 最终会在argskwds 中结束,具体取决于它的传递方式,手动解析星形参数可能很乏味。这里inspect.Signature 类,尤其是它的.bind.bind_partial 方法很有用。

functools.wraps 是一个便利函数/装饰器,它调整了装饰函数的许多特殊属性,使其看起来像被包装的函数。特别是它会复制名称、签名、文档字符串以及包装函数__dict__ 中可能包含的任何内容。

这使得包装函数更加用户友好。

【讨论】:

您应该解释functools.wraps 的实际作用,因为它实际上并不负责此处转发参数的任何部分。它只更新函数的__name__ 等元数据。 @user2357112 够公平的,会的。【参考方案2】:

看起来您正在寻找 *** 符号:

def outer_func(*args, **kwargs):
    inner_func(*args, **kwargs)

然后你可以做outer_func(1, 2, 3, a='x', b='y')outer_func会调用inner_func(1, 2, 3, a='x', b='y')

如果您只想允许关键字参数,请删除 *args


在函数定义中,标有* 的参数接收与其他声明的参数不对应的所有位置参数的元组,标有** 的参数接收所有关键字参数的字典t 对应其他声明的参数。

在函数调用中,使用* 为序列(或其他可迭代)参数添加前缀会将其解压缩为单独的位置参数,并使用** 作为映射参数的前缀将其解压缩为单独的关键字参数。

【讨论】:

..."不改变outer_func的定义" @wim:我很确定这意味着“每次更改 outer_func 时不更改 outer_func 的定义”,但我可能是错的。 啊,这是我没有考虑过的解释。 谢谢!这正是我一直在寻找的。我知道使用 * 作为参数,但我不知道您可以在传递函数参数时使用它来解包元组或字典。

以上是关于如何将关键字参数作为参数传递给函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何将字典传递给带有关键字参数的函数?

如何将带有 args 的成员函数作为参数传递给另一个成员函数?

如何将子类作为期望基类的函数的参数传递,然后将该对象传递给指向这些抽象类对象的指针向量?

如何将 JS 函数的引用作为参数传递给 ExternalInterface 调用?

将对象作为参数传递给函数

如何将 :new 作为参数传递给 oracle 客户函数?