This PEP describes a simpler string substitution feature, alsoknown as string interpolation. This PEP is “simpler” in tworespects:
%-substitution) is complicated and error prone. This PEPis simpler at the cost of some expressiveness.$ string prefix.PEP 292 is simpler thanthis because it involves no syntax changes and has much simplerrules for what substitutions can occur in the string.Python currently supports a string substitution syntax based onC’sprintf() ‘%’ formatting character[1]. While quite rich,%-formatting codes are also error prone, even forexperienced Python programmers. A common mistake is to leave offthe trailing format character, e.g. the ‘s’ in"%(name)s".
In addition, the rules for what can follow a% sign are fairlycomplex, while the usual application rarely needs such complexity.Most scripts need to do some string interpolation, but most ofthose use simple ‘stringification’ formats, i.e.%s or%(name)sThis form should be made simpler and less error prone.
We propose the addition of a new class, calledTemplate, whichwill live in the string module. TheTemplate class supports newrules for string substitution; its value contains placeholders,introduced with the$ character. The following rules for$-placeholders apply:
$$ is an escape; it is replaced with a single$$identifier names a substitution placeholder matching a mappingkey of “identifier”. By default, “identifier” must spell aPython identifier as defined in[2]. The first non-identifiercharacter after the$ character terminates this placeholderspecification.${identifier} is equivalent to$identifier. It is requiredwhen valid identifier characters follow the placeholder but arenot part of the placeholder, e.g."${noun}ification".If the$ character appears at the end of the line, or is followedby any other character than those described above, aValueErrorwill be raised at interpolation time. Values in mapping areconverted automatically to strings.
No other characters have special meaning, however it is possibleto derive from theTemplate class to define different substitutionrules. For example, a derived class could allow for periods inthe placeholder (e.g. to support a kind of dynamic namespace andattribute path lookup), or could define a delimiter characterother than$.
Once theTemplate has been created, substitutions can be performedby calling one of two methods:
substitute(). This method returns a new string which resultswhen the values of a mapping are substituted for theplaceholders in theTemplate. If there are placeholders whichare not present in the mapping, aKeyError will be raised.safe_substitute(). This is similar to thesubstitute() method,except thatKeyErrors are never raised (due to placeholdersmissing from the mapping). When a placeholder is missing, theoriginal placeholder will appear in the resulting string.Here are some examples:
>>>fromstringimportTemplate>>>s=Template('${name} was born in ${country}')>>>prints.substitute(name='Guido',country='the Netherlands')Guido was born in the Netherlands>>>prints.substitute(name='Guido')Traceback (most recent call last):[...]KeyError:'country'>>>prints.safe_substitute(name='Guido')Guido was born in ${country}
The signature ofsubstitute() andsafe_substitute() allows forpassing the mapping of placeholders to values, either as a singledictionary-like object in the first positional argument, or askeyword arguments as shown above. The exact details andsignatures of these two methods is reserved for the standardlibrary documentation.
$ and Braces?The BDFL said it best[3]: “The$ means “substitution” in so manylanguages besides Perl that I wonder where you’ve been. […]We’re copying this from the shell.”
Thus the substitution rules are chosen because of the similaritywith so many other languages. This makes the substitution ruleseasier to teach, learn, and remember.
PEP 215 describes an alternate proposal for string interpolation.Unlike that PEP, this one does not propose any new syntax forPython. All the proposed new features are embodied in a newlibrary module.PEP 215 proposes a new string prefixrepresentation such as$"" which signal to Python that a new typeof string is present.$-strings would have to interact with theexisting r-prefixes and u-prefixes, essentially doubling thenumber of string prefix combinations.
PEP 215 also allows for arbitrary Python expressions inside the$-strings, so that you could do things like:
import sysprint $"sys = $sys, sys = $sys.modules['sys']"
which would return:
sys=<module'sys'(built-in)>,sys=<module'sys'(built-in)>
It’s generally accepted that the rules inPEP 215 are safe in thesense that they introduce no new security issues (seePEP 215,“Security Issues” for details). However, the rules are stillquite complex, and make it more difficult to see the substitutionplaceholder in the original$-string.
The interesting thing is that theTemplate class defined in thisPEP is designed for inheritance and, with a little extra work,it’s possible to supportPEP 215’s functionality using existingPython syntax.
For example, one could define subclasses ofTemplate and dict thatallowed for a more complex placeholder syntax and a mapping thatevaluated those placeholders.
The implementation supports internationalization by recording theoriginal template string in theTemplate instance’stemplateattribute. This attribute would serve as the lookup key in angettext-based catalog. It is up to the application to turn theresulting string back into aTemplate for substitution.
However, theTemplate class was designed to work more intuitivelyin an internationalized application, by supporting the mixing-inofTemplate and unicode subclasses. Thus an internationalizedapplication could create an application-specific subclass,multiply inheriting fromTemplate and unicode, and using instancesof that subclass as the gettext catalog key. Further, thesubclass could alias the special__mod__() method to either.substitute() or.safe_substitute() to provide a more traditionalstring/unicode like%-operator substitution syntax.
The implementation[4] has been committed to the Python 2.4 source tree.
This document has been placed in the public domain.
Source:https://github.com/python/peps/blob/main/peps/pep-0292.rst
Last modified:2025-02-01 08:55:40 GMT