I am trying to understand this code from someone else’s project. If you want the context it’s here: https://github.com/newsapps/beeswithmachineguns/blob/master/beeswithmachineguns/bees.py#L501
IS_PY2 is just a boolean variable, True if the Python major version is 2.
I know that a non-empty string is True, but for some reason I don’t understand openmode is assigned either 'w' or 'wt' rather than True or False.
openmode = IS_PY2 and 'w' or 'wt'
openkwargs = IS_PY2 and {} or {'encoding': 'utf-8', 'newline': ''}
Could someone explain the result?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
The and and or operators don’t simply perform a boolean operation on their operands, giving a boolean result. The result they give is always one of their operands. These operators evaluate from left to right, with and having a higher precedence than or, and they short-circuit, meaning that they stop evaluating their operands as soon as possible.
In pure boolean logic, False and x is False, no matter what x is, so there’s no need to examine x. The Python expression False and x will give a result of False and it will not attempt to evaluate x. Thus False and some_function() will not call some_function().
Similarly, True and x in pure boolean 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 won’t 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
output
False 0 [] boolean integer string list False 0 []
(Those blank lines between 0 and [] are where the empty string is getting printed).
Similar considerations apply to the or operator.
In pure boolean logic, True or x is True, no matter what x is so if the first part of an or expression is True-ish we don’t need to evaluate the second part. And False or x has the truth value of 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
output
boolean integer string list True 7 a [42] False 0 []
As I said earlier, these operators are evaluated 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'
Those statements are equivalent to
print (True and 'yes') or 'no' print (False and 'yes') or 'no'
output
yes no
That construction was common in early versions of Python. These days, it’s far more common to see an if expression:
print 'yes' if True else 'no' print 'yes' if False else 'no'
Which is generally considered to be more readable than the ternary expression using and and or. Also, a and b or c is not equivalent to b if a else c if b is false-ish.
However, it’s still important to understand how this ternary and ... or thing works, especially if you need to read or maintain older code. And some old Pythonistas still prefer the and ... or form, as it’s slightly shorter even if it is a little bewildering when you don’t understand how it works. 🙂
Method 2
The ternary boolean expression works as:
>>> 2 and 3 or 4 3 >>> 0 and 3 or 4 4
So, this expression:
openmode = IS_PY2 and 'w' or 'wt'
Become in Python 2:
openmode = True and 'w' or 'wt'
Which is equivalent to
openmode = 'w' or 'wt'
So, i gives w.
Under Python 3, IS_PY2 is False, giving:
openmode = False and 'w' or 'wt'
Which is equivalent to
openmode = False or 'wt'
Giving wt.
All of this is to specify explicitely that the openmode is for text files, not binary, which is indicated by w in Python2 and wt in Python3.
While the Python3 t mode is the default one, this is not necessary to precise it.
See this answer about wt mode.
Finally, i think that the following is much more readable:
openmode = 'w' if IS_PY2 else 'wt'
And this one, much more simple:
openmode = 'w'
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0