13

是否可以有条件地将任意数量的命名默认参数传递给 Python 函数?

例如。有一个功能:

def func(arg, arg2='', arg3='def')

现在的逻辑是我有一个条件来确定是否需要传递 arg3,我可以这样做:

if condition == True:
    func('arg', arg2='arg2', arg3='some value')
else:
    func('arg', arg2='arg2')

问题是,我可以有一个速记,如:

func('arg', 'arg2', 'some value' if condition == True else # nothing so default gets picked
)
4

4 回答 4

10

我能想到的唯一方法是

func("arg", "arg2", **({"arg3": "some value"} if condition == True else {}))

或者

func("arg", "arg2", *(("some value",) if condition == True else ()))

但请不要这样做。使用您自己提供的代码或类似的代码:

if condition:
   arg3 = "some value",
else:
   arg3 = ()
func("arg", "arg2", *arg3)
于 2011-01-12T15:42:51.143 回答
9

那将不是有效的 Python 语法,您必须在else. 正常的做法是:

func('arg', 'arg2', 'some value' if condition else None)

并且函数定义相应更改:

def func(arg, arg2='', arg3=None):
    arg3 = 'def' if arg3 is None else arg3
于 2011-01-12T15:44:16.487 回答
4

如果你有一个有很多默认参数的函数

def lots_of_defaults(arg1 = "foo", arg2 = "bar", arg3 = "baz", arg4 = "blah"):
    pass

并且您想根据程序中发生的其他事情将不同的值传递给其中一些,一种简单的方法是使用**解压缩您根据程序逻辑构造的参数名称和值的字典。

different_than_defaults = {}
if foobar:
    different_than_defaults["arg1"] = "baaaz"
if barblah:
    different_than_defaults["arg4"] = "bleck"

lots_of_defaults(**different_than_defaults)

如果有很多逻辑确定您的调用中的内容,那么这样做的好处是在调用您的函数时不会阻塞您的代码。如果您有任何没有默认值的参数,则需要小心,在传递字典之前包含您为这些参数传递的值。

于 2011-01-12T17:48:00.050 回答
0

你可以写一个辅助函数

def caller(func, *args, **kwargs):
    return func(*args, **{k:v for k,v in kwargs.items() if v != caller.DONT_PASS})
caller.DONT_PASS = object()

使用此函数调用另一个函数并用于caller.DONT_PASS指定您不想传递的参数。

caller(func, 'arg', 'arg2', arg3 = 'some value' if condition else caller.DONT_PASS)

Note that this caller() only support conditionally passing keyword arguments. To support positional arguments, you may need to use module inspect to inspect the function.

于 2015-02-02T11:25:38.550 回答