Content-Type: RST As a Python and Free & Open-Source developer, you'd have expected my entry to be about `Google Wave`_ right now, since it was recently released and is an oh-so-beautiful piece of frickin awesomeness. Hmm, not writing about it... yet. Not until I get my hands on a developer sandbox. .. _`Google Wave`: http://wave.google.com Instead, a ramble about string formatting and Python 2.6/3.0, and why it is one of the more beautiful improvements to Python. Let's start at the beginning of string formatting. Remember this? .. sourcecode :: c int myAge = 17; char* myName = "Filip Sufitchi"; double pi = 3.14; char result[100]; sprintf(result, "%s is %d years old, and pi=%lf.", myName, myAge, pi); Yeah, good memories. There are still those who enjoy it, but as a Python programmer, I opt for easy over strict - especially since it took me an hour to figure out why ``%f`` only worked half the time if I used doubles. I was therefore glad that in Python, you could do the same thing with just ``%s`` and a ``%`` operator: .. sourcecode :: python myAge = 17 myName = 'Filip Sufitchi' pi = 3.14 result = '%s is %s years old and pi=%s' % (myName, myAge, pi) I was very happy with this at first, and still mostly am. However, I was starting to have some efficiency problems with it, something that should not happen in Python. I will use my blog for example. A paraphrase of my code (specifically, the links at the bottom of the blog entry) reads: .. sourcecode :: python document += """
""" % (postnumber,postnumber,postnumber,postnumber,postnumber) Disregarding my stupidity for not using a templating engine in the first place, doesnt %ing five versions of the very same value just seem wrong somehow? And, if I decide to remove one of those links, I have to alter the number of "postnumber"s found at the end too. It's a pain! Wouldn't it be more Pythonic to do this: .. sourcecode :: python document += """ """.format(p=postnumber) Of course it would be. It reduces the amount of tedious effort to do something like this, and removes yet another possible stupid coding mistake. Well, this is exactly what Python 2.6 and 3.0 support, via the new format() method of the str class. There was a debate about removing the old % method of doing things, but that idea was immediately shot down because of the enormous code rewritings necessary. Also the incessant whines of those who don't want to change off the old C-ish way of doing stuff. format() also includes some nice functionality that: - Allows it to replace % in its old usage - and exceed .. sourcecode :: python >>>'The first thing passed is {0}, and the second is {1}. The third is {2}.'.format(678,True,'wow') 'The first thing passed is 678, and the second is True. The third is wow.' >>> 'The first thing passed is {0}, and the second is {1}. The third is {2}. The first, again, is {0}.'.format(678,True,'wow') 'The first thing passed is 678, and the second is True. The third is wow. The first, again, is 678.' - Access stuff inside a dict to get its data .. sourcecode :: python >>> fsufitch = {'name':'Filip Sufitchi', 'age':17} >>> 'The object is {person}, but its name is {person[name]} and age is {person[age]}.'.format(person=fsufitch) "The object is {'age': 17, 'name': 'Filip Sufitchi'}, but its name is Filip Sufitchi and age is 17." >>> 'The object is {0}, but its name is {0[name]} and age is {0[age]}.'.format(fsufitch) "The object is {'age': 17, 'name': 'Filip Sufitchi'}, but its name is Filip Sufitchi and age is 17." - Access attributes of a passed object .. sourcecode :: python >>> class Wumpus: ... foo = 'bar' ... baz = 1337 ... >>> w = Wumpus() >>> 'obj.foo = {obj.foo} obj.baz = {obj.baz}'.format(obj=w) 'obj.foo = bar obj.baz = 1337' >>> 'obj.foo = {0.foo} obj.baz = {0.baz}'.format(w) 'obj.foo = bar obj.baz = 1337' - Manage your spacing - no, really! .. sourcecode :: python >>> template = '{name:^10}|${money:>6}' >>> def makeTable(record): ... print(template.format(name="Name", money="Cash")) ... print('-'*10 + '+' + '-'*7) ... for name,amount in record.items(): ... print(template.format(name=name, money=amount)) ... >>> money = {'Alice':48, 'Bob':80, 'Craig':-44, 'Filip':1337} >>> makeTable(money) Name |$ Cash ----------+------- Craig |$ -44 Bob |$ 80 Alice |$ 48 Filip |$ 1337