检查多个变量是否为无的最简单的方法是什么?

如果我有这样一个结构:

def foo():
a=None
b=None
c=None


#...loop over a config file or command line options...


if a is not None and b is not None and c is not None:
doSomething(a,b,c)
else:
print "A config parameter is missing..."

Python 中检查所有变量是否设置为有用值的首选语法是什么?是像我写的那样,还是另一种更好的方式?

这不同于这个问题: Not Nothing test in Python ... 我正在寻找检查许多条件是否为 Nothing 的首选方法。我键入的选项看起来很长,而且不是 pythonic。

79197 次浏览

你做事的方式没有错。

如果你有一个 很多的变量,你可以把它们放在一个列表中,并使用 all:

if all(v is not None for v in [A, B, C, D, E]):

其实可以简单得多

if None not in (a, b, c, d):
pass

更新:

正如 slashCoder 正确指出的那样,上面的代码隐式地执行 a = = None、 b = = None 等操作。这种做法是不允许的。相等运算符可以被重载,而“不”可以变成“无”。你可以说这从来没有发生过。它不会,直到它发生。所以,为了安全起见,如果您想检查没有一个对象是 Nothing,您可以使用这种方法

if not [x for x in (a, b, c, d) if x is None]:
pass

它有点慢,表现力不强,但仍然相当快和短。

我知道这是一个老问题,但我想添加一个答案,我认为这是更好的。

如果所有需要检查的元素都是散列的,那么您可以使用 set 而不是 list 或 tuple。

>>> None not in {1, 84, 'String', (6, 'Tuple'), 3}

这比其他答案中的方法要快得多。

$ python3 -m timeit "all(v is not None for v in [1, 84, 'String', (6, 'Tuple'), 3])"
200000 loops, best of 5: 999 nsec per loop


$ python3 -m timeit "None not in [1, 84, 'String', (6, 'Tuple'), 3]"
2000000 loops, best of 5: 184 nsec per loop


$ python3 -m timeit "None not in (1, 84, 'String', (6, 'Tuple'), 3)"
2000000 loops, best of 5: 184 nsec per loop


python3 -m timeit "None not in {1, 84, 'String', (6, 'Tuple'), 3}"
5000000 loops, best of 5: 48.6 nsec per loop

此方法的另一个优点是,即使有人定义了类的 __eq__方法以总是返回 True,它也会给出正确的答案。(当然,如果他们将 __hash__方法定义为 return hash(None),这个方法就不能工作。但是没有人应该这样做,因为这样做会破坏定义 hash 的目的。)

class Int(int):
def __eq__(self, other):
return True
def __hash__(self):
return hash(super())


print(all(v is not None for v in [1, Int(6), 2])) # True (correct)
print(None not in [1, Int(6), 2])                 # False (wrong)
print(None not in (1, Int(6), 2))                 # False (wrong)
print(None not in {1, Int(6), 2})                 # True (correct)

编辑: 正如 Mo2所指出的,如果任何变量被设置为 0,那么 这个解决方案将会失败被认为是一个“有用”的值。

对于 OP 提供的特定情况

if not all([a, b, c])

就足够了。

all([a, b, c])

evaluates to False if any parameter is missing.