Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 成对可选参数_Python - Fatal编程技术网

Python 成对可选参数

Python 成对可选参数,python,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 opt

我有一个带有两个可选参数的函数,我希望同时指定这两个参数,或者两者都不指定。在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.")      

这个问题:与我的问题相同,但具体是在
argparse
的上下文中;我对通常在函数中执行此操作的默认方式感兴趣。

您可以定义函数

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)
我不认为它比你最初的方法更好,但它更明确/可读

def myfunc(data, *args):
    if(len(args)==0 or len(args)==2):
        #do something
我会怎么做


这还使您能够拥有所需的任意多个参数,并且只有在不使用任何参数或使用2个参数时,代码才会运行

您要查找的简化条件是:

if (opt1 is None) != (opt2 is None):
    raise ...

如果两个参数不在
is None
的同一侧,则此条件为真。

您可以使用
集删除重复项的事实:

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

如果你既不需要也不需要两者,不要接受两个不同的论点;接受一个可选的元组并将其记录下来。不要给用户只提供一个的机会

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
可以是一个包含两个元素的iterable,但是如果用户发出类似于
myfunc(数据,“hi”)
的调用,并期望
opt1
hi
opt2
无,那是他的错,而不是你的错。)

如果(opt1为无)=(opt2为None):提高价值错误(…)
我认为您的方法是您所能做到的最好的方法。在Python中,除了在函数中使用if语句进行检查外,没有真正的“技巧”来强制两个或两个可选参数。这很公平,但我希望除此之外可能还有更多可选参数,并且计数可能会变得复杂。但是,我在问题中没有具体说明。如果元组是
(3,None)
,该怎么办?仍然存在同样的问题,我称之为用户错误;他们没有忘记提供第二个参数,他们明确选择根据文档化的需求提供
None
值。(最终,这归结为类型检查,在运行时,这通常是Python中调用方的责任。)我考虑过这一点,但在(3,无)情况下,我们可能会有代码产生不正确的行为。当然,我们可以在函数中使用显式检查来防止这种情况,但是我们的情况与以前相同。所以我不清楚元组到底有什么帮助。换言之,我们也可以不使用元组而依赖外部文档。我认为它的主要目的是更清楚地记录您的意图。有两个单独的参数和默认值强烈地意味着可以独立地忽略其中一个。只有一个论点就排除了这种可能性;您只能显式指定不正确的值,如
(3,无)
,而不允许使用默认值。您还可以更明确地定义元组应该是什么:两个
int
s、六个列表、一个
str
和一个
dict
,等等。