Python - logical evaluation order in “if” statement

♀尐吖头ヾ 提交于 2019-11-26 23:16:12

问题


In Python we can do this:

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
  • Can somebody point me to documentation on this feature?
  • Is it an implementation detail or feature of the language?
  • Is it good coding style to exploit this feature?

回答1:


The or and and short circuit, see the Boolean operations documentation:

The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.

The expression x or y first evaluates x; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.

Note how, for and, y is only evaluated if x evaluates to a True value. Inversely, for or, y is only evaluated if x evaluated to a False value.

For the first expression True or blah, this means that blah is never evaluated, since the first part is already True.

Furthermore, your custom Blah class is considered True:

In the context of Boolean operations, and also when expressions are used by control flow statements, the following values are interpreted as false: False, None, numeric zero of all types, and empty strings and containers (including strings, tuples, lists, dictionaries, sets and frozensets). All other values are interpreted as true. (See the __nonzero__() special method for a way to change this.)

Since your class does not implement a __nonzero__() method (nor a __len__ method), it is considered True as far as boolean expressions are concerned.

In the expression blah or blah.notexist, blah is thus true, and blah.notexist is never evaluated.

This feature is used quite regularly and effectively by experienced developers, most often to specify defaults:

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

Do be wary of chaining these and use a conditional expression instead where applicable.




回答2:


This is called short-circuiting and is a feature of the language:

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

The Boolean operators and and or are so-called short-circuit operators: their arguments are evaluated from left to right, and evaluation stops as soon as the outcome is determined. For example, if A and C are true but B is false, A and B and C does not evaluate the expression C. When used as a general value and not as a Boolean, the return value of a short-circuit operator is the last evaluated argument.




回答3:


It's the way the operators logical operators, specifically or in python work: short circuit evaluation.

To better explain it, consider the following:

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.

For more information see the following:

  • The official python documentation on boolean operations
  • A stack overflow question regarding short circuitry in python



回答4:


With the or operator, values are evaluated from left to right. After one value evaluates to True, the entire statement evaluates to True (so no more values are evaluated).

  • Official documentation
  • It's a feature of the language
  • There is nothing wrong with using its functionality


来源:https://stackoverflow.com/questions/16069517/python-logical-evaluation-order-in-if-statement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!