如何在带有* args和** kwargs的函数调用中使用默认参数?

时间:2018-10-18 13:03:22

标签: python function default

我有以下简单的示例代码:

def wrapper(foo, para1=1, *args):
    print("para1: "+ str(para1))
    print(foo(*args))

def foo1(x):
    return 2*x

wrapper(foo1, 2, 3)

其中定义了一个函数wrapper,该函数具有一个参数para1,其默认值为1

但是为了正确调用具有功能foo1的包装器,我必须一直设置para1,因为我必须将额外的参数传递给foo1。这意味着默认值para1=1没有任何意义,因为我一直都必须对其进行定义。

或者还有其他方法可以定义函数,这样我就可以轻松使用此默认值而不必一直定义它?

例如

wrapper(foo1, *args=(3,))
wrapper(foo=foo1, args=(3,))

不起作用...

用例:

def wrapper(foo, timeout=10, *args):
    time0 = time.time()
    while time0 < time.time() + timeout:
        if foo(*args):
             return True
        time.sleep(1)
    raise SomeTimeout Exception

3 个答案:

答案 0 :(得分:0)

您以接受数字的方式定义了foo1函数,但是您尝试在wrapper函数中将元组传递给它。 以下应该起作用:

def wrapper(foo, para1=1, *args):
    print("para1: "+ str(para1))
    print(foo(*args))



def foo1(*x):
    return 2*x


wrapper(foo1, (2, 3))

foo1 x中的定义更改为*x

答案 1 :(得分:0)

编辑:由于您已经清楚地表明它适用于Python 2,def wrapper(foo, *args, timeout=10)会给您带来语法错误。因此,请改用以下方法。

仅凭*args我就认为这不太可行。如有可能,尝试改用**kwargs

def wrapper(foo, *args, **kwargs):
    time0 = time.time()
    # define a default timeout period if not explicitly passed in by keyword
    timeout = kwargs.get('timeout') if 'timeout' in kwargs else 10
    while time0 < time.time() + timeout:
        if foo(*args):
            return True
        time.sleep(1)
    raise SomeTimeOut Exception

每次您要明确提供超时期限时,都应这样称呼:

wrapper(foo, 1, 2, 3, timeout=60)

Test code

def wrapper(foo, *args, **kwargs):
    timeout = kwargs.get('timeout') if 'timeout' in kwargs else 10
    print 'Timeout = {0}'.format(timeout)
    foo(*args)

def foo(*args):
    print 'Args = {0}'.format([a for a in args])

wrapper(foo, 1, 2, 3, timeout=20)

# Results
# Timeout = 20
# Args = [1, 2, 3]

答案 2 :(得分:0)

如何使它像这样?

#/usr/bin/env python3

def f1(f, *args, **kwargs):
    if not 'b' in kwargs:
        kwargs['b'] = 1
    print('b =',kwargs['b'])
    f(args)

def fx(args):
    print(args)

f1(fx, 3, 4)
print()
f1(fx, 3, 4, b=2)

输出:

b = 1                                                                     
(3, 4)

b = 2                                                                     
(3, 4)