replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"
field_name ::= arg_name ("." attribute_name | "[" element_index "]")*
在替換域中,!...
和:...
有意義呢!進入這些部分的內容也有嚴格的限制。
遞歸錯誤來自佔位符內佔位符內的多個嵌套{...}
佔位符; str.format()
和str.format_map()
不能支持大量的嵌套層次:
>>> '{foo:{baz: {ham}}}'.format_map({'foo': 'bar', 'baz': 's', 'ham': 's'})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Max string recursion exceeded
但是這裏還有其他問題:
最後兩可通過返回__format__
和__getitem__
和__getattr__
方法包裝對象走近,但只在有限的情況下:
>>> class FormatWrapper:
... def __init__(self, v):
... self.v = v
... def __format__(self, spec):
... return '{{{}{}}}'.format(self.v, (':' + spec) if spec else '')
... def __getitem__(self, key):
... return FormatWrapper('{}[{}]'.format(self.v, key))
... def __getattr__(self, attr):
... return FormatWrapper('{}.{}'.format(self.v, attr))
...
>>> class MissingDict(dict):
... def __missing__(self, key):
... return FormatWrapper(key)
...
>>> '{"foo.com": "bar[baz]", "ham": "eggs"}'.format_map(MissingDict())
'{"foo.com": "bar[baz]", "ham": "eggs"}'
>>> '{"foo .com": "bar [ baz ]", "ham": "eggs"}'.format_map(MissingDict())
'{"foo .com": "bar [ baz ]", "ham": "eggs"}'
這失敗的「空白」屬性:
>>> '{"foo...com": "bar[baz]", "ham": "eggs"}'.format_map(MissingDict())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Empty attribute in format string
簡而言之,格式對於包含的內容做了太多的假設ide {...}
花括號,假設JSON數據很容易中斷。
我建議你看看使用string.Template()
class來代替一個更簡單的模板系統,它可以被子類化;默認是查找並替換$identifier
字符串。 Template.safe_substitute()
method完全符合你的要求;替換已知的$identifier
佔位符,但保留未知名稱不變。