[Python-Dev] PEP 292, Simpler String Substitutions
Raymond Hettinger
python@rcn.com
Wed, 19 Jun 2002 02:45:46 -0400
From: "Barry A. Warsaw" <barry@zope.com>
> A Simpler Proposal
>
> Here we propose the addition of a new string method, called .sub()
> which performs substitution of mapping values into a string with
> special substitution placeholders. These placeholders are
> introduced with the $ character. The following rules for
> $-placeholders apply:
>
> 1. $$ is an escape; it is replaced with a single $
Hmm, some strings (at least in the spam I receive) contain $$$$$$.
How about ${$}?
> 2. $identifier names a substitution placeholder matching a mapping
> key of "identifier". "identifier" must be a Python identifier
> as defined in [2]. The first non-identifier character after
> the $ character terminates this placeholder specification.
+1
>
> 3. ${identifier} is equivalent to $identifier and for clarity,
> this is the preferred form. It is required for when valid
> identifier characters follow the placeholder but are not part of
> the placeholder, e.g. "${noun}ification".
+1
> Handling Missing Keys
>
> What should happen when one of the substitution keys is missing
> from the mapping (or the locals/globals namespace if no argument
> is given)? There are two possibilities:
>
> - We can simply allow the exception (likely a NameError or
> KeyError) to propagate.
>
> - We can return the original substitution placeholder unchanged.
And/Or,
- Leave placeholder unchanged unless default argument supplied:
mystr.sub(mydict, undefined='***') # Fill unknowns with
stars
And/Or,
- Raise an exception only if specified:
mystr.sub(mydict, undefined=NameError)
And/Or
- Return a count of the number of missed substitutions:
nummisses = mystr.sub(mydict)
> BDFL proto-pronouncement: It should always raise a NameError when
> the key is missing. There may not be sufficient use case for soft
> failures in the no-argument version.
I had written a minature mail-merge program and learned that the NameError
approach is a PITA. It makes sense if the mapping is defined inside the
program;
however, externally supplied mappings (like a mergelist) can be expected to
have "holes" and launching exceptions makes it harder to recover than having
a default behavior. The best existing Python comparison is the
str.replace() method which does not bomb-out when the target string is not
found.
Raymond Hettinger