Recipe 1.17. Interpolating Variables in a Stringin Python 2.4Credit: John Nielsen, Lawrence Oluyede, Nick Coghlan ProblemUsing 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. SolutionPython 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 DiscussionIn 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 AlsoLibrary Reference docs for string.Template (2.4 only) and the locals built-in function. |