Format string unused named arguments
You could use a template string with the safe_substitute
method.
from string import Template
tpl = Template('$bond, $james $bond')
action = tpl.safe_substitute({'bond': 'bond'})
You can follow the recommendation in PEP 3101 and subclass Formatter:
from __future__ import print_function
import string
class MyFormatter(string.Formatter):
def __init__(self, default='{{{0}}}'):
self.default=default
def get_value(self, key, args, kwds):
if isinstance(key, str):
return kwds.get(key, self.default.format(key))
else:
return string.Formatter.get_value(key, args, kwds)
Now try it:
>>> fmt=MyFormatter()
>>> fmt.format("{bond}, {james} {bond}", bond='bond', james='james')
'bond, james bond'
>>> fmt.format("{bond}, {james} {bond}", bond='bond')
'bond, {james} bond'
You can change how key errors are flagged by changing the text in self.default
to what you would like to show for KeyErrors:
>>> fmt=MyFormatter('">>{{{0}}} KeyError<<"')
>>> fmt.format("{bond}, {james} {bond}", bond='bond', james='james')
'bond, james bond'
>>> fmt.format("{bond}, {james} {bond}", bond='bond')
'bond, ">>{james} KeyError<<" bond'
The code works unchanged on Python 2.6, 2.7, and 3.0+
If you are using Python 3.2+, use can use str.format_map().
For bond, bond
:
from collections import defaultdict
'{bond}, {james} {bond}'.format_map(defaultdict(str, bond='bond'))
Result:
'bond, bond'
For bond, {james} bond
:
class SafeDict(dict):
def __missing__(self, key):
return '{' + key + '}'
'{bond}, {james} {bond}'.format_map(SafeDict(bond='bond'))
Result:
'bond, {james} bond'
In Python 2.6/2.7
For bond, bond
:
from collections import defaultdict
import string
string.Formatter().vformat('{bond}, {james} {bond}', (), defaultdict(str, bond='bond'))
Result:
'bond, bond'
For bond, {james} bond
:
from collections import defaultdict
import string
class SafeDict(dict):
def __missing__(self, key):
return '{' + key + '}'
string.Formatter().vformat('{bond}, {james} {bond}', (), SafeDict(bond='bond'))
Result:
'bond, {james} bond'
One can also do the simple and readable, albeit somewhat silly:
'{bar}, {fro} {bar}'.format(bar='bar', fro='{fro}')
I know that this answer requires knowledge of the expected keys, but I was looking for a simple two-step substitution (say problem name first, then problem index within a loop) and creating a whole class or unreadable code was more complex than needed.