python3.6で導入されるf文字列はformatメソッドとは違う
pythonで文字列フォーマットをするときには今のところ二通り方法があって、pythonには珍しく(?)統一されていない感じになっています。 で、python3.6では更に新しい方法が追加されるらしいです。 軽く使ってみたのですが、微妙にformatメソッドと違ったりして不思議な感じなので、軽くメモ。 記事執筆時点での開発版の仕様を元にしているので、もしかしたら正式版とは違うかもしれません。注意です。
とりあえず既存の一つめの方法。%式。式? 演算子?
>>> w = 'world' >>> 'hello %s' % w 'hello world'
こんなやつ。わりとよく見掛けるやつです。 フォーマット文字列の文法はなんとなくC言語とかのprintfに似てますね。
で、二つめの方法はformatメソッド。
>>> w = 'world' >>> 'hello {0}'.format(w) 'hello world'
こんなん。ちょっとモダンです。かなり高機能で、色々出来る。 一応これが推奨の方法らしいですが、bytesにも%でフォーマットする方法が導入されたりして、なんだかよくわからない。
そして、新しく導入されるのがf文字列ってやつ。
>>> w = 'world' >>> f'hello {w}' 'hello world'
シンプルっぽい。 ご覧の通り、というか何というか、変数名をそのまま使えるようになっています。
で、こいつ。formatメソッドと同じような構文で、同じことが出来るように見えます。
>>> n = 12 >>> f'{n:05d}' '00012' >>> s = 'hello' >>> f'{s: <7s}' 'hello'
ゼロ詰めとか、右寄せとか左寄せとか。
なんだー簡単じゃんと思うわけですが、微妙に仕様が違うようです。 どうも、変数名のところに普通のリテラルも書けるようです。 つまりどういうことかというと、普通の計算式を書ける。
>>> f'{12 + 34}' '46' >>> n = 1 >>> f'{n * 2}' '2' >>> a = 'hello' >>> b = 'world' >>> f'{a + " " + b}' 'hello world' >>> def func(x): ... return x * 2 ... >>> f'{func(2)}' '4'
おお、よくわからなくなってきた。
formatメソッドのときはどうだったかというと、計算しようとするとKeyErrorが出たりします。
>>> '{12 + 34}'.format() Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: '12 + 34'
うん、分かりやすい反応
それでも概ね使い方に違いは無さそうですが、とりあえず違いが影響しそうなのはdict型にアクセスするときとか。
>>> d = {'a': 1, 'b': 2} >>> '{0[a]}'.format(d) '1' >>> '{d[b]}'.format(d=d) '2' >>> '{0["a"]}'.format(d) Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: '"a"' >>> f'{d["a"]}' '1' >>> key = 'b' >>> f'{d[key]}' '2' >>> f'{d[a]}' Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'a' is not defined
こんなん。 普通の値か、それとも専用のミニ言語か、というような感じの違いなんでしょうね、きっと。 考えてみりゃ当然のことですが、ちょっとふしぎ。
文字列の定義と同時にしか使えない(多分)し、使えたとしてもセキュアじゃない感じがするし、既存の方法の置き換えというわけにはいかなそうです。 状況に応じて色々組み合せる必要性がありそう。うーむ。
参考: Pythonの新しい文字列フォーマット : %記号、str.format()から文字列補間へ | プログラミング | POSTD