如何将关键字参数作为参数传递给函数?
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
最终会在args
或kwds
中结束,具体取决于它的传递方式,手动解析星形参数可能很乏味。这里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 的成员函数作为参数传递给另一个成员函数?
如何将子类作为期望基类的函数的参数传递,然后将该对象传递给指向这些抽象类对象的指针向量?