在Python中用参数列表调用函数

171 投票
6 回答
386814 浏览
提问于 2025-04-15 11:22

我想在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 个回答

15

你问的问题的直接答案是,只需要修改这一行

func(args)

改成

func(*args)

这样做是告诉Python把给定的列表(在这个例子中是args)的内容作为位置参数传递给函数。

这个技巧在函数调用的“两边”都能用,所以像这样定义的函数:

def func2(*args):
    return sum(args)

可以接受你传入的任意数量的位置参数,并把它们全部放进一个叫args的列表里。

希望这能帮你更清楚一些。值得注意的是,使用字典/关键字参数时也可以做到这一点,只需用**代替*

27

包裹一个函数的最简单方法

    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
295

稍微详细解释一下其他回答:

在这一行:

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]

撰写回答