diveintopython.org
Python for experienced programmers

 

1.11. Formatting strings

All the real work of odbchelper.py is done in one line of code, and here it is.

    return ";".join(["%s=%s" % (k, params[k]) for k in params.keys()])

Don't panic. Ignore everything else and focus on the middle part, which is a string formatting expression. (If you're a C hacker, you can probably skim this part.)

Example 1.25. The middle part

"%s=%s" % (k, params[k])

Python supports formatting values in strings, like the sprintf function in C. The most basic usage is to simply insert a value in the place of the %s placeholder.

Example 1.26. Introducing string formatting

>>> params = {"uid":"sa", "pwd":"secret"}
>>> k = "uid"
>>> "%s=%s" % (k, params[k]) 1
'uid=sa'
>>> k = "pwd"
>>> "%s=%s" % (k, params[k]) 2
'pwd=secret'
1 The whole expression evaluates to a string. The first %s is replaced by the value of the k variable; the second %s is replaced by the value in the params dictionary whose key is k. All other characters in the string (in this case, the equals sign) stay as they are.
2 This expression works for any key in the dictionary. (“Hmm, that means it works for each key in the dictionary…in a loop…” Don't get ahead of yourself, it's coming.)

Note that (k, params[k]) is a tuple. I told you they were good for something.

You might be thinking that this is a lot of work just to do simple string concatentation, and you'd be right, except that string formatting isn't just concatenation. It's not even just formatting. It's also type coercion.

Example 1.27. String formatting vs. concatenating

>>> uid = "sa"
>>> pwd = "secret"
>>> print pwd + " is not a good password for " + uid      1
secret is not a good password for sa
>>> print "%s is not a good password for %s" % (pwd, uid) 2
secret is not a good password for sa
>>> userCount = 6
>>> print "Users connected: %s" % (userCount, )           3 4
Users connected: 6
>>> print "Users connected: " + userCount                 5
Traceback (innermost last):
  File "<interactive input>", line 1, in ?
TypeError: cannot add type "int" to string
1 + is the string concatenation operator.
2 In this trivial case, string formatting accomplishes the same result as concatentation.
3 (userCount, ) is a tuple with one element. Yes, the syntax is a little strange, but there are good reasons for it.
4 String formatting works, even though userCount is an integer. If the value being formatted is not a string, it is silently coerced into a string. Remember when I said that you have to be aware of when and how Python coerces data into different types? This is one of those cases.
5 Trying to concatenate a string with a non-string raises an exception. String concatenation only works when everything is a string.