dav*_*ers 5 python string-formatting python-2.7 python-3.3
简单使用Python的str.format()方法:
>>> '{0}'.format('zero')
'zero'
Run Code Online (Sandbox Code Playgroud)
十六进制,八进制和二进制文字不起作用:
>>> '{0x0}'.format('zero')
KeyError: '0x0'
>>> '{0o0}'.format('zero')
KeyError: '0o0'
>>> '{0b0}'.format('zero')
KeyError: '0b0'
Run Code Online (Sandbox Code Playgroud)
根据替换字段语法,他们应该:
Run Code Online (Sandbox Code Playgroud)replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}" field_name ::= arg_name ("." attribute_name | "[" element_index "]")* arg_name ::= [identifier | integer] attribute_name ::= identifier element_index ::= integer | index_string index_string ::= <any source character except "]"> + conversion ::= "r" | "s" format_spec ::= <described in the next section>
的整数语法如下:
Run Code Online (Sandbox Code Playgroud)longinteger ::= integer ("l" | "L") integer ::= decimalinteger | octinteger | hexinteger | bininteger decimalinteger ::= nonzerodigit digit* | "0" octinteger ::= "0" ("o" | "O") octdigit+ | "0" octdigit+ hexinteger ::= "0" ("x" | "X") hexdigit+ bininteger ::= "0" ("b" | "B") bindigit+ nonzerodigit ::= "1"..."9" octdigit ::= "0"..."7" bindigit ::= "0" | "1" hexdigit ::= digit | "a"..."f" | "A"..."F"
我是否误解了文档,或者Python的行为不像宣传的那样?(我使用的是Python 2.7.)
这看起来像是语法错误。文本中没有任何内容可以澄清这一点;它只是将其描述为“一个数字或一个标识符”,并讨论了如何解释它是一个数字。
\n\n测试一下,该字段显然不被视为integer:
>>> \'{08}\'.format(*range(10)) # should be SyntaxError\n\'8\'\n>>> \'{010}\'.format(*range(10)) # should be \'8\'\n\'10\'\n>>> \'{-1}\'.format(*range(10)) # should be \'9\', but looked up as a string\nKeyError: \'-1\'\n>>> \'{1 }\'.format(*range(10)) # should be \'1\', but looked up as a string\nKeyError: \'1 \'\n>>> \'{10000000000000000000}\'.format(1) # should be IndexError\nValueError: Too many decimal digits in format string\nRun Code Online (Sandbox Code Playgroud)\n\n看代码,它并没有借用Python解析器来解析格式字符串;它使用自定义解析,将 arg_spec 解释为数字的代码使用一个函数get_integer,该函数仅转换每个数字并移位并添加,直到该字段结束或我们进入 的数字内PY_SSIZE_T_MAX。
PEP 3101表明这是故意的:
\n\n\n\n\n简单的字段名称可以是名称或数字。如果是数字,则它们必须是有效的以 10 为基数的整数\xc2\xa0\xe2\x80\xa6
\n
它并没有具体说它不能太接近最大索引值,也没有说不能使用负索引。但大多数其他怪癖可以通过使用“有效的以 10 为基数的整数”描述来解释,而不仅仅是“整数”。事实上,只要将其描述为而digit +不是就integer可以解决所有的怪癖。
的element_index解析方式与 完全相同arg_name。#8985有意表示element_index“\xe2\x80\xa6 使用整数索引的最窄定义,以便将所有其他字符串传递给映射。” 我不确定这是否也是有意为之arg_name,或者是否是使用相同代码的意外结果。
我建议搜索错误跟踪器和python-dev档案,看看以前是否曾提出过这个问题。如果没有,请弄清楚您是否认为应该更改文档或代码,提交错误,最好提交补丁。
\n