Recipe1.17.Interpolating Variables in a Stringin Python 2.4


Recipe 1.17. Interpolating Variables in a Stringin Python 2.4

Credit: John Nielsen, Lawrence Oluyede, Nick Coghlan

Problem

Using Python 2.4, you need a simple way to get a copy of a string where specially marked identifiers are replaced with the results of looking up the identifiers in a dictionary.

Solution

Python 2.4 offers the new string.Template class for this purpose. Here is a snippet of code showing how to use that class:

import string # make a template from a string where some identifiers are marked with $ new_style = string.Template('this is $thing') # use the substitute method of the template with a dictionary argument: print new_style.substitute({'thing':5})      # emits: this is 5 print new_style.substitute({'thing':'test'}) # emits: this is test # alternatively, you can pass keyword-arguments to 'substitute': print new_style.substitute(thing=5)          # emits: this is 5 print new_style.substitute(thing='test')     # emits: this is test

Discussion

In Python 2.3, a format string for identifier-substitution has to be expressed in a less simple format:

old_style = 'this is %(thing)s'

with the identifier in parentheses after a %, and an s right after the closed parenthesis. Then, you use the % operator, with the format string on the left of the operator, and a dictionary on the right:

print old_style % {'thing':5}      # emits: this is 5 print old_style % {'thing':'test'} # emits: this is test

Of course, this code keeps working in Python 2.4, too. However, the new string.Template class offers a simpler alternative.

When you build a string.Template instance, you may include a dollar sign ($) by doubling it, and you may have the interpolated identifier immediately followed by letters or digits by enclosing it in curly braces ({ }). Here is an example that requires both of these refinements:

form_letter = '''Dear $customer, I hope you are having a great time. If you do not find Room $room to your satisfaction, let us know. Please accept this $$5 coupon.             Sincerely,             $manager             ${name}Inn''' letter_template = string.Template(form_letter) print letter_template.substitute({'name':'Sleepy', 'customer':'Fred Smith',                                   'manager':'Barney Mills', 'room':307,                                  })

This snippet emits the following output:

Dear Fred Smith, I hope you are having a great time. If you do not find Room 307 to your satisfaction, let us know. Please accept this $5 coupon.             Sincerely,             Barney Mills             SleepyInn

Sometimes, the handiest way to prepare a dictionary to be used as the argument to the substitute method is to set local variables, and then pass as the argument locals( ) (the artificial dictionary whose keys are the local variables, each with its value associated):

msg = string.Template('the square of $number is $square') for number in range(10):     square = number * number     print msg.substitute(locals( ))

Another handy alternative is to pass the values to substitute using keyword argument syntax rather than a dictionary:

msg = string.Template('the square of $number is $square') for i in range(10):     print msg.substitute(number=i, square=i*i)

You can even pass both a dictionary and keyword arguments:

msg = string.Template('the square of $number is $square') for number in range(10):     print msg.substitute(locals( ), square=number*number)

In case of any conflict between entries in the dictionary and the values explicitly passed as keyword arguments, the keyword arguments take precedence. For example:

msg = string.Template('an $adj $msg') adj = 'interesting' print msg.substitute(locals( ), msg='message') # emits an interesting message

See Also

Library Reference docs for string.Template (2.4 only) and the locals built-in function.



Python Cookbook
Python Cookbook
ISBN: 0596007973
EAN: 2147483647
Year: 2004
Pages: 420

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net