我有一个带有两个可选参数的函数,我想要两者都要求,或者都不需要指定。在Python中强制执行此操作的首选方法是什么?我目前的做法似乎有点尴尬:
def myfunc(data, opt1=None, opt2=None):
if opt1 is None or opt2 is None:
if not (opt1 is None and opt2 is None):
raise ValueError("Must specify both opt1 and opt2 or neither.")
这个问题:Python Optional Argument Pair与我的相同,但在argparse
的具体情况下;我对在函数中的默认方式感兴趣。
答案 0 :(得分:3)
您正在寻找的简化条件是:
if (opt1 is None) != (opt2 is None):
raise ...
如果两个论点不在is None
的同一侧,则这种情况属实。
答案 1 :(得分:1)
您可以定义一个功能
def ensure_both_or_neither(opt1, opt2):
if opt1 is None or opt2 is None:
if not (opt1 is None and opt2 is None):
raise ValueError("Must specify both opt1 and opt2 or neither.")
然后从你的函数中调用它:
def myfunc(data, opt1=None, opt2=None):
ensure_both_or_neither(opt1, opt2)
我认为它不比你的原始方法好,但它更明确/可读?
答案 2 :(得分:1)
def myfunc(data, *args):
if(len(args)==0 or len(args)==2):
#do something
我是怎么做的
这也使您可以拥有任意数量的参数,并且只有在使用无或2时才运行代码
答案 3 :(得分:1)
您可以使用set
删除重复项的事实:
def myfunc(data, opt1=None, opt2=None):
if len({opt1 is None, opt2 is None}) - 1:
raise ValueError("Must specify both opt1 and opt2 or neither.")
您可以为任意数量的参数执行此操作:
def myfunc(data, *args):
if len({arg is None for arg in args}) - 1:
raise ValueError("Must specify all parameters or none.")
答案 4 :(得分:0)
如果你不需要或两者,不要接受两个单独的论点;接受一个可选的元组和文档它。不要让用户只提供一个。
def myfunc(data, opts=None):
"""blah blah blah
opts, if given, should be a tuple with two values, neither None.
"""
opt1, opt2 = opts if opts is not None else (None, None)
您可以设置默认的(None, None)
,这样可以简化函数内部的解包(x1, x2 = opts
),但会以使函数的签名混乱为代价。
(实际上,opts
可以是包含2个元素的可迭代,但如果用户进行myfunc(data, "hi")
之类的调用并且期望opt1
为hi
和{{ 1}}成为opt2
,这是他的错,不是你的错。)