带有“:”和“/”的键的字符串格式

String formatting for keys with ":" and "/"

带有 :/ 的格式字符串。当尝试使用值 dict 进行格式化时,它会抛出:

ValueError: Missing ']' in format string

示例:

In [312]: value
Out[312]: {'key:/key_part': 1}

In [313]: string_to_format
Out[313]: '{v[key:/key_part]}'

In [314]: string_to_format.format(v=SafeDict(value))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-314-3ee97d9dfb86> in <module>()
----> 1 string_to_format.format(v=SafeDict(value))

ValueError: Missing ']' in format string

其中 SafeDict 是此 SO answer 中使用的实现。

In [311]: class SafeDict(dict):
     ...:     def __missing__(self, key):
     ...:         return "NULL"

关于如何解决这个问题有什么想法吗?

这是字符串格式化实现中使用的基本解析的已知限制。 Simple and Compound Field Names in PEP 3101 部分描述了 str.format 语法中的 'getitem' 支持(强调我的):

An example of the 'getitem' syntax:

"My name is {0[name]}".format(dict(name='Fred'))

It should be noted that the use of 'getitem' within a format string is much more limited than its conventional usage. In the above example, the string 'name' really is the literal string 'name', not a variable named 'name'. The rules for parsing an item key are very simple. If it starts with a digit, then it is treated as a number, otherwise it is used as a string.

Because keys are not quote-delimited, it is not possible to specify arbitrary dictionary keys (e.g., the strings "10" or ":-]") from within a format string.

稍后在“实施说明”下:

The str.format() function will have a minimalist parser which only attempts to figure out when it is "done" with an identifier (by finding a '.' or a ']', or '}', etc.).

所以这是 str.format 设计的缺点。细心的 reader 可能会注意到 OP 的字符串格式在 Python 3 中有效。一些边缘情况在 Python 3.4 中得到了修补,但同样的问题在 Python 中仍然存在3.3 及以下版本。

相关票证是issue12014: str.format parses replacement field incorrectly。由于 Python 2.7 现在已停产,将 Python 3.4 的这些改进移植到 2.7 的可能性为零,因此您必须在两个选项之间做出选择:

  1. 升级到Python 3
  2. 重构您的代码,使字符串格式仅使用简单的名称或数字