如何检查python中至少有一个指定函数的默认参数

问题描述 投票:6回答:5

在python中检查是否至少指定了该函数的一个默认参数是什么?

我们假设我们有一些功能:

def some_function(arg_a=None, arg_b=None, arg_c=False)

有一些默认参数。在我的情况下,我需要检查是否指定了arg_aarg_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方法是什么?

python function parameter-passing
5个回答
6
投票

你可以使用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的解释实际上是什么。


4
投票

取决于您对arg_aarg_b的预期值,但这通常就足够了。

if not arg_a and not arg_b:
    raise ValueError(...)

假设arg_aarg_b不是布尔值,并且不能有零,空字符串/列表/元组等作为参数。

根据您的需要,如果您需要区分None和'falsies',例如False,0,“”,[],{},()等,您可以更精确:

if arg_a is None and arg_b is None:
    raise ValueError(...)

1
投票

如果你有很多这样的命名参数与默认值不匹配,你可以考虑使用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)

0
投票

检查是否至少指定了一个函数的默认参数

使用localsdict.valuesany函数的解决方案:

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

https://docs.python.org/2/library/functions.html#any


0
投票

既然你提出了这样的模式,那么arg_aarg_barg_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。然而,它将由类型检查器拾取。

© www.soinside.com 2019 - 2024. All rights reserved.