有条件地传递任意数量的默认命名参数给函数

13 投票
4 回答
4643 浏览
提问于 2025-04-16 09:50

有没有办法在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 个回答

5

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

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)

这样做的好处是,当你调用这个函数时,不会让代码变得很乱,特别是当你需要很多逻辑来决定传什么值的时候。不过,如果你有一些没有默认值的参数,要小心在传递字典之前,确保把这些参数的值也包含进去。

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

撰写回答