我尝试在 python 中的另一个函数中调用一个函数,但是找不到正确的语法。我想做的是这样的:
def wrapper(func, args): func(args) def func1(x): print(x) def func2(x, y, z): return x+y+z wrapper(func1, [x]) wrapper(func2, [x, y, z])
在这种情况下,第一个调用将工作,而第二个调用将不工作。 我要修改的是包装函式而不是被调用的函数。
可以对可变长度的参数使用 * args 和 * * kwargs 语法。
Args 和 kwargs 是什么意思?
以及官方的 Python 教程
Http://docs.python.org/dev/tutorial/controlflow.html#more-on-defining-functions
你需要使用的参数解包. 。
def wrapper(func, *args): func(*args) def func1(x): print(x) def func2(x, y, z): print x+y+z wrapper(func1, 1) wrapper(func2, 1, 2, 3)
为了扩展一下其他的答案:
排队:
def wrapper(func, *args):
args旁边的 * 表示“获取给定的其余参数,并将它们放在名为 args的列表中”。
args
func(*args)
在这里,args旁边的 * 表示“将这个名为 args 的列表取出,并将其‘展开’到其余的参数中。
所以你可以这样做:
def wrapper1(func, *args): # with star func(*args) def wrapper2(func, args): # without star func(*args) def func2(x, y, z): print x+y+z wrapper1(func2, 1, 2, 3) wrapper2(func2, [1, 2, 3])
在 wrapper2中,列表是显式传递的,但是在这两个包装器中,args都包含列表 [1,2,3]。
wrapper2
[1,2,3]
对于您的问题,字面上的答案(要完全按照您的要求做,只更改包装器,而不是函数或函数调用)仅仅是更改行
func(args)
读书
这告诉 Python 获取给定的列表(在本例中是 args) ,并将其内容作为位置参数传递给函数。
这个技巧对函数调用的“两边”都适用,因此定义如下的函数:
def func2(*args): return sum(args)
可以接受尽可能多的位置参数,并将它们全部放入名为 args的列表中。
我希望这有助于澄清一些事情。请注意,这对于 dicts/关键字参数也是可能的,使用的是 **而不是 *。
**
*
包装函数的最简单方法
func(*args, **kwargs)
就是手动编写一个封装器,在其内部调用 Func ():
def wrapper(*args, **kwargs): # do something before try: return func(*a, **kwargs) finally: # do something after
在 Python 中函数是一个对象,因此您可以将它的名称作为另一个函数的参数传递并返回它。您还可以为任何函数 AnyFunc ()编写包装生成器:
def wrapperGenerator(anyFunc, *args, **kwargs): def wrapper(*args, **kwargs): try: # do something before return anyFunc(*args, **kwargs) finally: #do something after return wrapper
还请注意,在 Python 中,当你不知道或者不想给函数的所有参数命名时,你可以引用参数元组,参数元组由其名称表示,在函数名称后面的括号中加一个星号:
*args
例如,您可以定义一个接受任意数量参数的函数:
def testFunc(*args): print args # prints the tuple of arguments
Python 甚至提供了对函数参数的进一步操作。可以允许函数接受关键字参数。在函数体中,关键字参数保存在字典中。在函数名后面的圆括号中,这个字典用两个星号表示,后面跟着字典的名称:
**kwargs
打印关键字参数字典的类似示例:
def testFunc(**kwargs): print kwargs # prints the dictionary of keyword arguments
这是对以前答案的一个小补充,因为我找不到一个问题的解决方案,这不值得打开一个新的问题,但引导我来到这里。
下面是一个结合了 lists、 zip()和 *args的小代码片段,它提供了一个包装器,可以处理未知数量的函数和未知数量的参数。
lists
zip()
def f1(var1, var2, var3): print(var1+var2+var3) def f2(var1, var2): print(var1*var2) def f3(): print('f3, empty') def wrapper(a,b, func_list, arg_list): print(a) for f,var in zip(func_list,arg_list): f(*var) print(b) f_list = [f1, f2, f3] a_list = [[1,2,3], [4,5], []] wrapper('begin', 'end', f_list, a_list)
请记住,zip()不提供不等长列表的安全检查,见 在 python 中断言等长的 zip 迭代器。