Python - "if"语句中的逻辑评估顺序

14

在Python中,我们可以这样做:

if True or blah:
    print("it's ok") # will be executed

if blah or True: # will raise a NameError
    print("it's not ok")

class Blah:
    pass
blah = Blah()

if blah or blah.notexist:
    print("it's ok") # also will be executed
  • 有人可以指引我查看该特性的文档吗?
  • 这是语言的实现细节还是特性?
  • 利用这个特性是否符合良好的编码风格?

1
“blah or True” 这个语句对我来说不会引发异常,它会打印输出。 - Tim S.
5
只有在你先定义了“blah”的情况下才能这样做。请注意,在示例顶部,“blah”尚未定义,因此会引发“NameError”错误。 - Martijn Pieters
4个回答

35
orand 具有短路特性,请参考 布尔运算 文档:

表达式 x and y 首先计算 x,如果 x 的值为 false,则返回其值;否则,计算 y 并返回结果。

表达式 x or y 首先计算 x,如果 x 的值为 true,则返回其值;否则,计算 y 并返回结果。

请注意,在 and 中,只有在 x 的值为 True 时才会计算 y。相反地,在 or 中,只有在 x 的值为 False 时才会计算 y

对于第一个表达式 True or blah,这意味着因为第一部分已经是 True,所以 blah 永远不会被计算。

此外,你自定义的 Blah 类被认为是 True:

在布尔运算上下文中,以及在表达式用于控制流语句时,以下值被解释为 false: FalseNone、所有类型的数字零以及空字符串和容器(包括字符串、元组、列表、字典、集合和不可变集合)。所有其他值都被解释为 true。 (有关更改此行为的方法,请参见 __nonzero__() 特殊方法。)

由于你的类没有实现 __nonzero__() 方法(也没有实现 __len__ 方法),因此在布尔表达式中,它被视为 True。

在表达式 blah or blah.notexist 中,blah 为 true,而 blah.notexist 永远不会被计算。

这个特性经常被熟练的开发人员使用,通常用于指定默认值:

some_setting = user_supplied_value or 'default literal'
object_test = is_it_defined and is_it_defined.some_attribute

要小心链接这些内容,并在适当的情况下使用条件表达式代替。


7
这被称为短路计算,是语言的一个特性:

布尔运算符and和or是所谓的短路运算符:它们的参数从左到右进行求值,并且一旦结果确定,计算就停止了。例如,如果A和C为真但B为假,则A and B and C不会评估表达式C。当作为一般值而不是布尔值使用时,短路运算符的返回值是最后计算的参数。

http://docs.python.org/2/tutorial/datastructures.html#more-on-conditions

3
这是操作符逻辑运算,特别是在 Python 中使用的 or 运算符的工作方式:短路求值。
为了更好地解释它,请考虑以下内容:
if True or False:
    print('True') # never reaches the evaluation of False, because it sees True first.

if False or True:
    print('True') # print's True, but it reaches the evaluation of True after False has been evaluated.

更多信息请参见以下内容:

2

使用 or 运算符时,值从左到右进行评估。当一个值评估为 True 时,整个语句将评估为 True(因此不会再评估更多的值)。

  • 官方文档
  • 这是一种语言特性
  • 使用其功能没有任何问题

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