首页 > 解决方案 > 为什么与“是”的布尔比较如此可怕?

问题描述

风格指南如下:

# 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”之间有区别吗?

标签: pythonbooleanboolean-expression

解决方案


为什么是这样?

因为它在逻辑上是错误的,类别错误。随着is您明确地执行身份检查,参考比较。但这不是你打算在这里做的。代码的目的是检查一个值是否为真(或更严格地说,是True)。该值是否恰好与常量位于内存中的同一地址True不仅无关紧要,而且会分散注意力。

换句话说,代码的意图与表达式的有关,因此检查它的,而不是它的引用标识


推荐阅读