使Python 3函数接受预设的正确方法是什么?

时间:2021-11-21 14:30:17

Consider a function that takes three arguments:

考虑一个带有三个参数的函数:

def foo(arg1, arg2, arg3):
    pass

and a class that provides presets in a tuple:

以及在元组中提供预设的类:

class Presets():
    preset1 = (1, 2, 3)
    preset2 = (3, 2, 1)

What's the proper way to make the function accept either three seperate arguments or one tuple of arguments?

使函数接受三个单独的参数或一个参数元组的正确方法是什么?

Both should be valid function calls:

两者都应该是有效的函数调用:

foo(1,1,1)
foo(Presets.preset2)

2 个解决方案

#1


4  

One way to do it is by using a decorator.

一种方法是使用装饰器。

from functools import wraps

def tupled_arguments(f):
    @wraps(f)  # keeps name, docstring etc. of f
    def accepts_tuple(tup, *args):
        if not args:  # only one argument given
            return f(*tup)
        return f(tup, *args)
    return accepts_tuple

@tupled_arguments
def foo(arg1, arg2, arg3):
    pass

Now the function can be called by either passing all arguments seperately or by passing them in a sequence.

现在可以通过单独传递所有参数或者按顺序传递它们来调用该函数。

foo(1,2,3)
foo((1,2,3))
foo([1,2,3])

are all equal calls.

都是平等的电话。

#2


3  

The simplest way is to just use an asterisk * to cause the arguments to be flattened when passed to foo:

最简单的方法是使用星号*使参数在传递给foo时变平:

foo(*Presets.preset2)

This is equivalent to:

这相当于:

foo(*(3, 2, 1))

which is equivalent to:

这相当于:

foo(3, 2, 1)

#1


4  

One way to do it is by using a decorator.

一种方法是使用装饰器。

from functools import wraps

def tupled_arguments(f):
    @wraps(f)  # keeps name, docstring etc. of f
    def accepts_tuple(tup, *args):
        if not args:  # only one argument given
            return f(*tup)
        return f(tup, *args)
    return accepts_tuple

@tupled_arguments
def foo(arg1, arg2, arg3):
    pass

Now the function can be called by either passing all arguments seperately or by passing them in a sequence.

现在可以通过单独传递所有参数或者按顺序传递它们来调用该函数。

foo(1,2,3)
foo((1,2,3))
foo([1,2,3])

are all equal calls.

都是平等的电话。

#2


3  

The simplest way is to just use an asterisk * to cause the arguments to be flattened when passed to foo:

最简单的方法是使用星号*使参数在传递给foo时变平:

foo(*Presets.preset2)

This is equivalent to:

这相当于:

foo(*(3, 2, 1))

which is equivalent to:

这相当于:

foo(3, 2, 1)