5

Python のstr.format()メソッドの簡単な使用:

>>> '{0}'.format('zero')
'zero'

16 進数、8 進数、および 2 進数のリテラルは機能しません。

>>> '{0x0}'.format('zero')
KeyError: '0x0'
>>> '{0o0}'.format('zero')
KeyError: '0o0'
>>> '{0b0}'.format('zero')
KeyError: '0b0'

ただし、置換フィールドの文法によると、次のようにする必要があります。

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>

整数の文法は次のとおりです。

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 を使用しています。)

4

1 に答える 1

4

これは文法の間違いのようです。そして、テキストにはそれを明確にするものは何もありません。「数値または識別子」として説明し、数値の場合にどのように解釈されるかについて説明します。

それをテストすると、フィールドは明らかに として扱われませんinteger:

>>> '{08}'.format(*range(10)) # should be SyntaxError
'8'
>>> '{010}'.format(*range(10)) # should be '8'
'10'
>>> '{-1}'.format(*range(10)) # should be '9', but looked up as a string
KeyError: '-1'
>>> '{1 }'.format(*range(10)) # should be '1', but looked up as a string
KeyError: '1 '
>>> '{10000000000000000000}'.format(1) # should be IndexError
ValueError: Too many decimal digits in format string

コードを見ると、Python パーサーから借用してフォーマット文字列を解析していません。カスタム解析を使用し、 arg_spec を数値として解釈するコードは、get_integer各桁を変換するだけの関数を使用し、フィールドが終了するか、 の桁になるまでシフトして追加しますPY_SSIZE_T_MAX

PEP 3101は、これが意図的であることを示唆しています:

単純なフィールド名は、名前または数値です。数値の場合、それらは有効な 10 進数の整数でなければなりません…</p>

最大インデックス値に近すぎてはならないことや、負のインデックスを使用できないことは特に述べていません。しかし、他の癖のほとんどは、単に「整数」の代わりに「有効な 10 進数の整数」の説明を使用して説明できます。実際、それをdigit +代わりに記述するだけで、すべての癖integerが解決されます。

element_index、 とまったく同じ方法で解析されarg_nameます。#8985は、element_index意図的に「…他のすべての文字列をマッピングに渡すために、整数インデックスに可能な限り狭い定義を使用する」と述べています。これも意図的なものarg_nameなのか、それとも同じコードを使用したことによる意図しない結果なのかはわかりません。

ドキュメントは3.4で変更されておらず、コードは現在のトランクで事実上変更されていません。

バグトラッカーpython-devアーカイブを検索して、これが以前に発生したかどうかを確認することをお勧めします。そうでない場合は、ドキュメントまたはコードを変更する必要があるかどうかを判断し、バグを報告し、理想的にはパッチを送信します。

于 2013-10-05T22:45:13.333 に答える