如果我有这个功能:
def foo(arg_one, arg_two):
pass
我可以像这样包装它:
def bar(arg_one, arg_two):
return foo(arg_one, arg_two)
foo = bar
是否可以在不知道foo必需参数的情况下执行此操作,如果是,如何执行此操作?
答案 0 :(得分:5)
您可以使用参数解包运算符(或任何they're called):
def bar(*args, **kwargs):
return foo(*args, **kwargs)
如果您不打算传递任何关键字参数,则可以删除**kwargs
。
答案 1 :(得分:4)
您可以使用*args
和**kwargs
:
def bar(*args, **kwargs):
return foo(*args, **kwargs)
args
是位置参数列表。
kwargs
是关键字参数的字典。
请注意,调用这些变量args
和kwargs
只是一个命名约定。 *
和**
为解包参数做了很多魔术。
另见:
答案 2 :(得分:2)
这是另一个稍微一般的用例(除了Blender的回答):
通常在扩展对象时在OOP中,实际上需要覆盖方法并且(小心地)扩展甚至更改签名(扩展方法的参数的顺序和数量),例如,在作为对象构造函数的__init__()
方法中。
以下是如何为此目的应用* args,** kwds的示例:
class Foo(object):
def __init(self, foo_positional_arg, foo_optional_arg=None):
pass
class Bar(Foo):
def __init__(self, bar_postional_arg, bar_optional_arg=None, *args, **kwds):
self.bar_postional_arg = bar_postional_arg
self.bar_optional_arg = bar_optional_arg
super(Bar, self).__init__(*args, **kwds)
实际上,实际上可以改变签名的顺序或者从先前(包装的)完整或部分签名中捕获参数。
def __init__(self, bar_postional_arg, foo_positional, foo_optional_arg=False, bar_optional_arg=None, *args, **kwds):
再次证明了python函数(和方法)中的* args,** kwds机制是多么灵活(!)。
答案 3 :(得分:0)
除了alecxe's answer之外,如果您希望包装器保留签名(换句话说,它看起来像是包装的函数一样对用户显示),您可能希望看看{{1 }}及其替代品functools.wraps
,可以解决一些缺陷,并将其用法扩展到您想要修改签名的情况。有关差异的简短说明,请参见here。我是makefun.wraps
的作者;)
这是您的编码方式:
makefun