在Python中用参数列表调用函数
我想在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])
在这个例子中,第一个调用会成功,而第二个调用则不会。我想修改的是外层的函数,而不是被调用的函数。
6 个回答
你问的问题的直接答案是,只需要修改这一行
func(args)
改成
func(*args)
这样做是告诉Python把给定的列表(在这个例子中是args
)的内容作为位置参数传递给函数。
这个技巧在函数调用的“两边”都能用,所以像这样定义的函数:
def func2(*args):
return sum(args)
可以接受你传入的任意数量的位置参数,并把它们全部放进一个叫args
的列表里。
希望这能帮你更清楚一些。值得注意的是,使用字典/关键字参数时也可以做到这一点,只需用**
代替*
。
包裹一个函数的最简单方法
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
稍微详细解释一下其他回答:
在这一行:
def wrapper(func, *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]
。