配对的可选参数

时间:2016-03-08 14:19:37

标签: python

我有一个带有两个可选参数的函数,我想要两者都要求,或者都不需要指定。在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的具体情况下;我对在函数中的默认方式感兴趣。

5 个答案:

答案 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")之类的调用并且期望opt1hi和{{ 1}}成为opt2,这是他的错,不是你的错。)