如果 x:,与 if x == True,与 if x is True 的区别。

41

如果此前已经有人提出过这个问题,我很抱歉,但我搜索了很久也没有找到 完全 符合我的问题的答案。基本上,使用 Python 2.7,我正在运行一系列地理处理工具的程序,这些工具取决于用户在脚本中调整的一系列 True/False 变量。

x = True

if x:
    run function

然而,我现在发现x不需要字面上为“True”才能运行该函数。例如:

In: x = True
    if x:
        print True

Out: True

In: x = 123
    if x:
        print True

Out: True

In: x = 'False'
    if x:
        print True

Out: True

In: x = False
    if x:
        print True

Out: 
因此,除了False之外的任何值似乎都会被认为是True的,这在如果使用 x == True x is True 的情况下并非如此。由于PEP 8强烈建议仅使用 if x:变体,是否有人能解释一下为什么会出现这种行为?看起来 if x:更多是一个测试,“如果x不是False”或“如果x存在”。考虑到这一点,我认为在这种情况下应该使用 if x is True:,尽管PEP 8有所不同。
8个回答

50
以下Python中的值在if和其他逻辑上下文中为假:
  • False
  • None
  • 数值等于0,如00.0-0.0
  • 空字符串:''u''
  • 空容器(例如列表、元组和字典)
  • 任何实现__bool__(Python 3)返回False或实现__nonzero__(Python 2)返回False0的东西。
  • 任何未实现__bool__(Python 3)或__nonzero__(Python 2),但实现了__len__以返回值为0的东西。

如果满足上述条件之一,则对象被认为是“false”,否则为“true”,无论它是否实际上等于或与FalseTrue相同

现在,如果您安排了x必须是TrueFalse对象之一,那么您可以安全地编写if x。如果您安排x的“真实性”指示是否执行操作,而不考虑类型,则可以安全地编写if x。如果可以编写,您应该优先这样做,因为它更容易阅读。

通常情况下,如果允许x取值True,则您处于这两种情况之一,因此您将不会编写if x is True。重要的是正确记录x的含义,以便反映代码中使用的测试。

Python程序员需要知道什么被认为是真值,因此如果你只记录“如果x为真,则运行函数”,那么这就表达了你原始代码的含义。记录“如果x is True,则运行函数”会有不同的含义,并且由于PEP8中的样式规则建议测试真值而不是特定值True而很少使用。

但是,如果您希望代码在x为空容器和None的情况下具有不同的行为,则可以编写类似于if x is not None的内容。


感谢您详细的解释。在我的情况下,虽然我只希望用户使用True或False,而不是其他值,但代码已经足够记录以遵循PEP 8并保留我的if x语句。 - ssast

5

我想添加一个简短的示例,说明这3个测试的区别:

def test(x):
    print(x, ":", bool(x), x == True, x is True)

test("something")
test(1)
test(True)

输出结果(格式化后):
# "something" : True False False
#           1 : True True  False
#        True : True True  True

3
x = 'False'
x = 123

两者都是 True

其他真值.

文档解释了其他值.

至于PEP8的原因,读起来更有语义化的是 if this_file_is_green


+1 for the link,没想到我一直在看一个较旧版本的Python教程,而且没有这么详细的内容。 - ssast

1

其他假值包括0''[]。您应该只使用if x:版本。


1
毋庸置疑,您应该编写能够满足需求的代码。但在大多数情况下,您不需要写 == Trueis True,因为您不需要区分 True 和其他“真值”。因此,为了简单起见,建议省略它们。
当您确实需要区分 True 和其他真值时,您绝对应该使用 == Trueis True
在您的示例中,您是否关心 True123 之间的区别?这将告诉您如何编码。
关于编写 == Trueis True 的一点事情:当其他开发人员阅读您的代码时,这将引起轻微的警惕。他们不会认为它是错误的,他们只会想知道为什么要在这种特殊情况下将 True 与其他真值区分开来。
换句话说,如果您不需要它,请不要使用它。

0

表达能力

if x:
   ...

被认为是一种功能。您还可以指定何时应考虑用户定义类的测试是否通过(只需在Python 2.x中定义方法 __nonzero__ 或在Python 3中定义方法 __bool__ )。

例如,对于字符串和容器(如列表、字典或集合),测试 if x ... 表示“如果x不为空”。

请注意,理由不是这样可以减少编写的代码,而是生成的代码更易于阅读和理解。

如果您喜欢编写 if x is True ... ,是否已经考虑过走得更远,例如 if (x is True) is True ... if ((x is True) is True) is True ... ? :-)


5
你知道x的值为True的结果只能是TrueFalse,但你可能不知道对于x也是同样的情况。因此,在极少数情况下,如果True具有与其他真值不同的特殊含义,那么这就可以避免无限递归的问题。 - Steve Jessop
我理解你的意思,尽管我不确定为什么有人会编写“if(x is True)is True”的代码。这就像使用“if(x == False)== False”一样。在这一点上,我同意Steve的看法。 - ssast

0

如果你使用 if x ,它意味着需要评估x的真值。但是当你使用 x == True 或者 x is True时,这意味着检查 type(x)==bool 和 x 是否为 True。

注意x is True 不等于 bool(x)==True

当你使用 x is True 时,你正在检查x和True的id是否相同。


0
在Python 2.7中,对于不等于1的值,if a:if a==True并不会产生相同的输出。以下是一些代码片段,以演示不同的行为:

a=1

a=1
if a==True: 
    print (a,"True")
else:
    print (a,"Not True")

output> (1,True)

a=1
if a: 
    print (a,"True")
else:
    print (a,"Not True")

output> (1, True)

使用a=2

a=2
if a: 
    print (a,"True")
else:
    print (a,"Not True")

output> (2, True)

a=2
if a==True: 
    print (a,"True")
else:
    print (a,"Not True")

output> (2, Not True)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接