前置き
先日、書式指定文字列の構文規則を確認する機会があった。
置換フィールドの文法は以下です:
replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}" field_name ::= arg_name ("." attribute_name | "[" element_index "]")* arg_name ::= [identifier | digit+] attribute_name ::= identifier element_index ::= digit+ | index_string index_string ::= <any source character except "]"> + conversion ::= "r" | "s" | "a" format_spec ::= <described in the next section>
引用元: Python3.6.5 標準ライブラリ » string » 書式指定文字列の文法
腑に落ちない点
前述の構文規則について、index_stringの定義が腑に落ちない。
文字列リテラルではなく、単に文字列を要求しているのだ。
実際に試してみると、この仕様の歪さが浮かんでくる。
>>> dct = {'answer': 42}
>>>
>>> '{0[answer]}'.format(dct)
'42'
>>>
>>> '{0["answer"]}'.format(dct)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: '"answer"'
例えば、キーとして文字列42
を指定できない。
>>> dct = {42: 'integer', '42': 'string'}
>>>
>>> '{0[42]}'.format(dct)
'integer'
>>>
>>> '{0["42"]}'.format(dct)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: '"42"'
f-string
一方、Python3.6以降で導入されたf-stringはこの問題を解消している。
>>> f'{dct[42]}'
'integer'
>>>
>>> f'{dct["42"]}'
'string'
便利になった一方、一貫性がないという不満もある。