For some reason this function confused me:
def protocol(port):
return port == \"443\" and \"https://\" or \"http://\"
Can somebody expl
This is an ugly hack that is not recommended. It works because of the short-circuiting behaviour of and
and or
and that they return the one of their arguments rather than a boolean value. Using this technique gives a risk of introducing hard-to-find bugs, so don't use it in new code.
Here's an example of how the and/or
idiom can give an unexpected result:
>>> foo = 'foobar'
>>> bar = 'foobar'
>>> x = 0
>>> y = 1
>>> (foo == bar) and x or y # Will this return the value of x if (foo == bar)?
1
Prefer instead the newer notation:
return "https://" if port == "443" else "http://"
You may want to read up on the "and / or trick" of Python in this article The Peculiar Nature of And and Or in Python. It's a bit like the IIF()
in VBA or VB, or ?:
in C-style languages.
and
returns the right operand if the left is true. or
returns the right operand if the left is false. Otherwise they both return the left operand. They are said to coalesce.
With all the good answers, I found these statements help me remember this better and fit how my brain works (and hopefully for for some more out there) :
“and" returns the first False item (e.g., None, “”, [], (), {}, 0) or the last item if none (e.g. no False found)
“or" returns the first True item or the last item (e.g. no True found)**
In summary:
Note this rule also applies to a chained all "and" or all "or" statement
C and X or Y
is the long-running early attempt by Python users to proxy for C ? X : Y
For the most part it works, except if X
is False
-- this has led to many bugs in Python code, so in the Python FAQ, you'll find the more correct solution being (C and [X] or [Y])[0]
because a list with a single element, regardless of its evaluated Boolean value, is always True
! For example: [None]
is True
but None
isn't. The OP's example above works because the string representing X
is not empty.
However, all this changed in Python 2.5, when the ternary or conditional operator was added to the language, allowing you to use the cleaner X if C else Y
as stated in other posts here. If you see code using the older format, it's because the user has been a long time Python programmer who hasn't adopted the new syntax yet, they cut-n-paste other old code, or their employer is still using 2.4.x (or earlier releases), etc.
This construction works because it 'unfolds' to the following code:
a and b -->
if a:
return b
else:
return a
a or b -->
if a:
return a
else:
return b