<p><a href="http://www.python.org/dev/peps/pep-3101/">PEP 3101</a>中的建议是将<a href="http://docs.python.org/2/library/string.html#string.Formatter">Formatter</a>子类化:</p>
<pre><code>import string
class PartialFormatter(string.Formatter):
def __init__(self, missing='~~', bad_fmt='!!'):
self.missing, self.bad_fmt=missing, bad_fmt
def get_field(self, field_name, args, kwargs):
# Handle a key not found
try:
val=super(PartialFormatter, self).get_field(field_name, args, kwargs)
# Python 3, 'super().get_field(field_name, args, kwargs)' works
except (KeyError, AttributeError):
val=None,field_name
return val
def format_field(self, value, spec):
# handle an invalid format
if value==None: return self.missing
try:
return super(PartialFormatter, self).format_field(value, spec)
except ValueError:
if self.bad_fmt is not None: return self.bad_fmt
else: raise
fmt=PartialFormatter()
data = {'n': 3, 'k': 3.141594, 'p': {'a': '7', 'b': 8}}
print(fmt.format('{n}, {k:.2f}, {p[a]}, {p[b]}', **data))
# 3, 3.14, 7, 8
del data['k']
data['p']['b'] = None
print(fmt.format('{n}, {k:.2f}, {p[a]:.2f}, {p[b]}', **data))
# 3, ~~, !!, ~~
</code></pre>
<p>按照设置,如果找不到字段或属性,则它将打印<code>~~</code>;如果给定字段值,则使用无效格式,则它将打印<code>!!</code>。(如果希望引发值错误的默认值,只需使用<code>None</code>作为关键字参数<code>bad_fmt</code>。)</p>
<p>要处理丢失的键,您需要对<code>get_field</code>进行子类化,以捕获<code>KeyError</code>或<code>AttributeError</code>和<code>format_field</code>来返回丢失键的默认值。</p>
<p>由于您捕获的是<code>format_field</code>错误,因此也可以通过捕获超类中的<code>ValueError</code>来捕获错误的格式字段。</p>