首页 > 解决方案 > 带有“:”和“/”的键的字符串格式

问题描述

带有:/存在的格式字符串。当尝试使用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"

关于如何度过这个难关的任何想法?

标签: pythonpython-2.7string-formatting

解决方案


这是字符串格式化实现中使用的基本解析的一个已知限制。PEP 3101中的简单和复合字段名称部分描述了语法中的“getitem”支持(强调我的):str.format

“getitem”语法的一个例子:

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

应该注意的是,在格式字符串中使用“getitem”比其常规用法要受限得多。在上面的示例中,字符串“name”实际上是文字字符串“name”,而不是名为“name”的变量。解析项目键的规则非常简单。如果它以数字开头,则将其视为数字,否则将其用作字符串。

因为键不是用引号分隔的,所以不可能从格式字符串中指定任意字典键(例如,字符串“10”或“:-]”)

后来在“实施说明”下:

str.format()函数将具有一个极简解析器,它仅尝试使用标识符(通过查找“.”或“]”或“}”等)来确定何时“完成”。

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

相关票证是issue12014: str.format parses replacement field wrongly。由于 Python 2.7 现在已经停产,因此将这些改进从 Python 3.4 向后移植到 2.7 的机会为零,因此您必须在两个选项之间进行选择:

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

推荐阅读