在python中检查是否至少指定了该函数的一个默认参数是什么?
我们假设我们有一些功能:
def some_function(arg_a=None, arg_b=None, arg_c=False)
有一些默认参数。在我的情况下,我需要检查是否指定了arg_a
或arg_b
。所以我想实现这样的事情:
def some_function(arg_a=None, arg_b=None, arg_c=False):
...
if arg_a is not None:
...
elif arg_b is not None:
...
else:
raise ValueError('Expected either arg_a or arg_b args')
...
...
那么,实现这种功能的更多pythonic方法是什么?
你可以使用all
检查它们是否都等于None
并提高ValueError
:
if all(v is None for v in {arg_a, arg_b}):
raise ValueError('Expected either arg_a or arg_b args')
这摆脱了那些if-elif
条款并将所有支票放在同一个地方:
f(arg_a=0) # ok
f(arg_b=0) # ok
f() # Value Error
或者,使用any()
:
if not any(v is not None for v in {arg_a, arg_b}):
raise ValueError('Expected either arg_a or arg_b args')
但这肯定更加模糊。
最后,它实际上取决于pythonic的解释实际上是什么。
取决于您对arg_a
和arg_b
的预期值,但这通常就足够了。
if not arg_a and not arg_b:
raise ValueError(...)
假设arg_a
和arg_b
不是布尔值,并且不能有零,空字符串/列表/元组等作为参数。
根据您的需要,如果您需要区分None和'falsies',例如False,0,“”,[],{},()等,您可以更精确:
if arg_a is None and arg_b is None:
raise ValueError(...)
如果你有很多这样的命名参数与默认值不匹配,你可以考虑使用kwargs
:
def some_function(**kwargs):
reqd = ['arg_a', 'arg_b']
if not all(i in kwargs for i in reqd):
raise ValueError('Expected either {} args'.format(' or '.join(reqd)))
arg_a = kwargs.get('args_a')
arg_b = kwargs.get('args_b')
arg_c = kwargs.get('args_c', False)
检查是否至少指定了一个函数的默认参数
使用locals
,dict.values
和any
函数的解决方案:
def some_function(arg_a=None, arg_b=None, arg_c=False):
args = locals()
if (any(args.values()) == True):
print('Ok')
else:
raise ValueError('At least one default param should be passed!')
some_function(False, 1) # Ok
some_function('text', False, None) # Ok
some_function(0, False, None) # Error
既然你提出了这样的模式,那么arg_a
,arg_b
和arg_c
可能会有一些统一的含义。如果是这样,你可以......
from enum import Enum
class Group(Enum):
A = auto()
B = auto()
C = auto()
def some_function(val: int, t: Group):
if t == Group.A:
# do stuff with val
elif t == Group.B:
# do other stuff with val
elif t == Group.C:
# do other stuff with val
some_function(1, Group.A)
这里调用者被强制指定一个值,以及该值对应的值。这是在python中缺乏适当的枚举支持的一点点,我不知道它是否是pythonic。然而,它将由类型检查器拾取。