开发者

Python logic in assignment

Given that secure is a bool开发者_运维技巧ean, what do the following statements do?

Especially the first statement.

  1. protocol = secure and "https" or "http"
  2. 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()
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜