样式指南读取如下:
# Correct:
if greeting:
# Wrong:
if greeting == True:
# Worse:
if greeting is True:
参见PEP 8,搜索“worse”一词。
为什么这样做?我习惯于尽可能明确地检查条件,以使代码更易读,并捕获异常。
考虑下面的函数:
def f(do_it):
if do_it : print("doit")
else : print("no don't")
它容易被滥用/监视,并产生意外的行为
>>> f("False")
doit
>>> f([False])
doit
当你检查一个返回值可能无意中通过if语句的情况时,这是一个真正的问题。可以通过使用is
结构来避免这种情况。
显然,PEP建议有很好的理由,但是是什么呢?
评论者的进一步研究导致了以下发现:
if x:
调用x所属类的__bool 方法。该方法应根据对象自身认定为True还是False而返回其中之一。
if x==True:
调用 x 类的 __eq 方法。该方法应能将自身与 True(或 False)进行比较,并根据情况返回 True 或 False。
if x is True
这不会调用它们。这个测试检查x是否是"True"对象。它完全绕过了__eq和__bool方法。
注意: 我不是在问"=="和"is"之间的区别。如果您是因为这个问题而来,请参见"=="和"is"之间有什么区别吗?
bool
与True
进行比较是多余和误导性的。它表明“这可能是True
,也可能是False
,或者可能是其他东西”。它已经是一个bool
了。你不需要继续将其与True
进行比较。如果x
是一个bool
,那么以下语句是等效的:if x:
,if x == True:
,if (x == True) == True:
,if ((x == True) == True) == True:
等等。只有其中一个是没有无用、误导性垃圾的:if x:
。 - Tom Karzesx == True
并不比x
更明确,它只是毫无意义的冗长。至于在这里使用is
,根本没有任何积极的理由,无论是明确性还是其他方面。相反,当你测试一个值时,你正在错误地使用引用语义。关于你的例子,如果你想避免类型错误,请使用类型注释和类型检查器。 - Konrad Rudolphbool
类型的值时在运行时失败。实际上已经有类似的限制存在,只不过相对宽松一些。这是一个明智决策,而非动态类型的副作用。 - Konrad Rudolph