2012-08-07 23 views
12

的差异对于我的其中一个站点,我需要检查是否定义了几个类属性而不是空的。到目前为止,我很高兴地使用if self.attr:,这在我看来是if self.attr is not None and self.attr is not '':的缩写,或者是属性的未定义值。字符串和运算符:最佳实践,与+

这工作正常,但在检查多个字符串属性时产生令人惊讶的行为。 '' and ''不是False(如我所料),但''

这引出了一个问题:and操作员是否还有其他类型的操作员不强制将类型转换为bool? 我不能拿出一个例子,这种行为上的差异会导致if条款的实际不同结果(毕竟,''仍然评估为False),但我们仍然觉得有边缘案例可能成为一个陷阱。

最后,我很想知道是否有人知道它为什么以这种方式实现?我认为Python的禅宗只鼓励一种方式,一种方式,并且运算符似乎是字符串连接的直观方式。

+1

你可以把代码放在这里吗? – 2012-08-07 12:48:50

+1

答案似乎没有涵盖这个问题,侧重于问题的布尔部分,但'和'从来没有字符串连接;它根本不像'+'。 – geoffspear 2012-08-07 13:09:27

+1

[使用'''.join'连接字符串,而不是'+'。](http://stackoverflow.com/questions/1349311/python-string-join-is-faster-than-but-whats-wrong-这里/ 1350289#1350289) – unutbu 2012-08-07 13:14:12

回答

13

and从来没有类型转换为布尔值。相反,if对表达式的结果调用bool()

使用and(和or,就此而言)的表达,短路时,它能够确定的是,表达不会评价为True或基于所述第一操作数False,并且返回最后一个评价值:

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

这种“副作用”通常用于python代码。请注意0​​确实返回一个布尔值。有关详细信息,请参阅python documentation on boolean operators

该文档还解释了什么是TrueFalse相当于各种类型,如None0''和空集装箱被False,而大多数其他一切等同于True

对于定制类,你需要定义.__nonzero__() method(返回TrueFalse)或.__len__() method(返回一个int,其中0False和其他一切是True),以影响他们的布尔等价的,否则他们将永远默认为True