Python logic in assignment
Given that secure
is a bool开发者_运维技巧ean, what do the following statements do?
Especially the first statement.
protocol = secure and "https" or "http"
newurl = "%s://%s%s" % (protocol,get_host(request),request.get_full_path())
I hate this Python idiom, it's completely opaque until someone explains it. In 2.6 or higher, you'd use:
protocol = "https" if secure else "http"
It sets protocol
to "https" if secure
is true, else it sets it to "http".
Try it in the interpreter:
>>> True and "https" or "http"
'https'
>>> False and "https" or "http"
'http'
Python generalises boolean operations a bit, compared to other languages. Before the "if" conditional operator was added (similar to C's ?:
ternary operator), people sometimes wrote equivalent expressions using this idiom.
and
is defined to return the first value if it's boolean-false, else returns the second value:
a and b == a if not bool(a) else b #except that a is evaluated only once
or
returns its first value if it's boolean-true, else returns its second value:
a or b == a if bool(a) else b #except that a is evaluated only once
If you plug in True
and False
for a
and b
in the above expressions, you'll see that they work out as you would expect, but they work for other types, like integers, strings, etc. as well. Integers are treated as false if they're zero, containers (including strings) are false if they're empty, and so on.
So protocol = secure and "https" or "http"
does this:
protocol = (secure if not secure else "https") or "http"
...which is
protocol = ((secure if not bool(secure) else "https")
if bool(secure if not bool(secure) else "https") else "http")
The expression secure if not bool(secure) else "https"
gives "https" if secure is True
, else returns the (false) secure
value. So secure if not bool(secure) else "https"
has the same truth-or-falseness as secure
by itself, but replaces boolean-true secure
values with "https". The outer or
part of the expression does the opposite - it replaces boolean-false secure
values with "http", and doesn't touch "https", because it's true.
This means that the overall expression does this:
- if
secure
is false, then the expression evaluates to "http" - if
secure
is true, then the expression evaluates to "https"
...which is the result that other answers have indicated.
The second statement is just string formatting - it substitutes each of the tuple of strings into the main "format" string wherever %s
appears.
The first line was answered well by the Ned and unwind.
The 2nd statement is a string replacement. Each %s is a placeholder for a string value. So if the values are:
protocol = "http"
get_host(request) = "localhost"
request.get_full_path() = "/home"
the resulting string would be:
http://localhost/home
In psuedocode:
protocol = (if secure then "https" else "http")
newurl = protocol + "://" + get_host(request) + request.get_full_path()
精彩评论