Boolean string assignment

I am trying to understand this code from another project. If you want the context to be here: https://github.com/newsapps/beeswithmachineguns/blob/master/beeswithmachineguns/bees.py#L501

IS_PY2 is just a boolean True if the major version of Python is 2. I know that the non-empty string is True , but for some reason I don’t understand that openmode is assigned either 'w' or 'wt' , not True or False

 openmode = IS_PY2 and 'w' or 'wt' openkwargs = IS_PY2 and {} or {'encoding': 'utf-8', 'newline': ''} 

Can someone explain the result?

+6
source share
2 answers

The ternary boolean expression works like:

 >>> 2 and 3 or 4 3 >>> 0 and 3 or 4 4 

So this expression:

 openmode = IS_PY2 and 'w' or 'wt' 

Get in Python 2:

 openmode = True and 'w' or 'wt' 

Which is equivalent

 openmode = 'w' or 'wt' 

So, I give w .

In Python 3, IS_PY2 is False, giving:

 openmode = False and 'w' or 'wt' 

Which is equivalent

 openmode = False or 'wt' 

Providing wt .


All this is to explicitly indicate that openmode is for text files, not binary files, as specified in w in Python2 and wt in Python3.

As long as Python3 t mode is standard, it is not necessary to define it accurately.

See this answer about wt mode .


Finally, I believe the following is more readable:

 openmode = 'w' if IS_PY2 else 'wt' 

And this one, much simpler:

 openmode = 'w' 
+7
source

The and and or operators do not just perform a logical operation on their operands, giving a logical result. The result they give is always one of their operands. These operators evaluate from left to right, with and having a higher priority than or , and they are short-circuited, which means that they stop evaluating their operands as soon as possible.

In pure logic, False and x is False , regardless of what x , so there is no need to examine x . The Python expression False and x will give the result False and will not try to evaluate x . Thus, False and some_function() will not call some_function() .

Similarly, True and x in pure logic will have the same truth value as x , i.e. if x is True , then True and x is True , otherwise its False .

But the Python and operator can handle arbitrary operands.

In a and b , if a is false-ish, then b will not be evaluated, and the result will be a . If a is true-ish, then b will be evaluated and become the result.

Here's a short demo using Python 2:

 print False and 'boolean' print 0 and 'integer' print '' and 'string' print [] and 'list' print print True and 'boolean' print 7 and 'integer' print 'a' and 'string' print [42] and 'list' print print True and False print True and 0 print True and '' print True and [] print 

Exit

 False 0 [] boolean integer string list False 0 [] 

(These blank lines between 0 and [] are where the blank line is printed).

Similar considerations apply to the or operator.

In pure logic, True or x is True , regardless of what x is, if the first part of the expression is True-ish, we do not need to evaluate the second part. And False or x has the truth value x .

 print False or 'boolean' print 0 or 'integer' print '' or 'string' print [] or 'list' print print True or 'boolean' print 7 or 'integer' print 'a' or 'string' print [42] or 'list' print print False or False print False or 0 print False or '' print False or [] print 

Exit

 boolean integer string list True 7 a [42] False 0 [] 

As I said, these operators are evaluated from left to right, and we can chain them if we want. Here are the classic cases:

 print True and 'yes' or 'no' print False and 'yes' or 'no' 

These statements are equivalent.

 print (True and 'yes') or 'no' print (False and 'yes') or 'no' 

Exit

 yes no 

This construct was common in earlier versions of Python. These days, the if much more common:

 print 'yes' if True else 'no' print 'yes' if False else 'no' 

It is generally considered more readable than a triple expression using and and or . In addition, a and b or c not equivalent to b if a else c if b is false-ish.

However, it’s still important to understand how this triple and ... or thing works, especially if you need to read or save the old code. And some old Pythonistas still prefer the and ... or form, as it is a little shorter, even if it is a little confusing when you don't understand how it works. :)

+10
source

All Articles