12

对于我的一个站点,我需要检查多个类属性是否已定义且不为空。到目前为止,我很高兴地使用if self.attr:了 ,在我看来它是 的简写if self.attr is not None and self.attr is not '':,或者属性的未定义值是什么。

这很好用,但在检查多个字符串属性时会产生令人惊讶的行为。'' and ''不是False(如我所料),而是''.

这就引出了一个问题:是否存在其他类型的and运算符不强制类型转换的类型bool?我想不出一个例子,这种行为差异会导致 - 子句的实际结果不同if(毕竟,''仍然评估为False),但我直觉认为存在可能是陷阱的边缘情况。

最后,我很想知道是否有人知道为什么要这样实施?我认为 Python 的 Zen 鼓励一种方式,而且只鼓励一种方式,而+运算符似乎已经是字符串连接的直观方式。

4

1 回答 1

13

and从不类型转换为 bool。相反,if调用bool()表达式的结果。

使用and(and or,就此而言)的表达式,当它可以确定表达式不会根据第一个操作数计算为 True 或 False 时会短路,并返回最后一个计算值:

>>> 0 and 'string'
0
>>> 1 and 'string'
'string'
>>> 'string' or 10
'string'
>>> '' or 10
10

这种“副作用”经常用在 python 代码中。请注意,它not 确实返回一个布尔值。有关详细信息,请参阅有关布尔运算符的 python 文档

该文档还解释了各种类型的 aTrue或等价物的构成,例如 ,和空容器 being ,而大多数其他内容都等价于.FalseNone0''FalseTrue

对于自定义类,您需要定义.__nonzero__()方法(返回TrueFalse)或.__len__()方法(返回一个 int,其中0isFalse和其他所有内容是True),以影响它们的布尔等效项,否则它们将始终默认为True.

于 2012-08-07T12:49:19.257 回答