简体   繁体   English

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

[英]How to use default arguments in a function call with *args and **kwargs?

I have the following simple example code:我有以下简单的示例代码:

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

def foo1(x):
    return 2*x

wrapper(foo1, 2, 3)

where I define a function wrapper that has one parameter para1 with default value 1 .在那里我定义了一个函数wrapper ,它有一个参数para1和默认值1

But in order to call the wrapper with function foo1 correctly, I have to set para1 all the time, because I have to pass the extra arguments to foo1 .但是为了正确调用带有函数foo1的包装器,我必须一直设置para1 ,因为我必须将额外的参数传递给foo1 That means the default value para1=1 does not make any sense, as I have to define it all the time anyway.这意味着默认值para1=1没有任何意义,因为无论如何我必须一直定义它。

Or is there some other way to define the functions so I can easilz make use of this default value without to have to define it all the time?或者有没有其他方法来定义函数,这样我就可以轻松使用这个默认值而不必一直定义它?

For example,例如,

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

does not work ...不工作...

Use case example:用例示例:

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

You defined the foo1 function in a way that accepts a number, but you try to pass a tuple to it in the wrapper function.您以接受数字的方式定义了foo1函数,但您尝试在wrapper函数中将元组传递给它。 the following should work:以下应该工作:

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



def foo1(*x):
    return 2*x


wrapper(foo1, (2, 3))

in the definition of foo1 x changed to *x .foo1的定义中x更改为*x

Edit: Since you have now made it clear it is for Python 2, def wrapper(foo, *args, timeout=10) would give you a syntax error.编辑:由于您现在已经明确表示它适用于 Python 2,因此def wrapper(foo, *args, timeout=10)会给您一个语法错误。 So use the below method instead.所以改用下面的方法。

With just *args alone I don't think it's very feasible.仅使用*args我认为这不太可行。 If possible, try making use of **kwargs instead:如果可能,请尝试使用**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

Every time you want to explicitly provide a timeout period, call it as such:每次要明确提供超时期限时,请按如下方式调用:

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]

What about making it like this?弄成这个样子怎么样?

#/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)

Output:输出:

b = 1                                                                     
(3, 4)

b = 2                                                                     
(3, 4)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM