是否可以有条件地将任意数量的命名默认参数传递给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
)
答案 0 :(得分: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
答案 1 :(得分:6)
我能想到的唯一方法就是
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)
答案 2 :(得分:1)
如果你的函数有很多默认参数
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)
如果有很多逻辑确定您的呼叫是什么,这样做的好处是不会在调用您的函数时堵塞您的代码。如果你有任何没有默认值的参数,你需要小心,在传递字典之前包含你传递的值。
答案 3 :(得分: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)
请注意,此caller()
仅支持有条件地传递关键字参数。要支持位置参数,您可能需要使用模块inspect
来检查函数。