読者です 読者をやめる 読者になる 読者になる

Python 3.6の新機能f-strings(フォーマット文字列リテラル)について

今までのPythonには文字列をフォーマットする方法が標準機能で3種類あった(%, str.format(), string.Template)。pythonはたったひとつの冴えたやり方を求める言語じゃないんですか?*1などと皮肉るのは簡単だが、実際に便利だし、主観的な評価としてはこの程度の便利さを求めたところでコードの分かりやすさは損なわれることはないと思う。まあ飽くまで乱用しない限り。ほどほどに…お手柔らかに…

さて新しくリリースされたpython 3.6では、ここに第4の文字列整形法が導入された。それが掲題のf-strings(PEP -- Literal String Interpolationである。f-stringsはこれまでの文字列フォーマットのだるいところを解決するために導入された。

使い方

とにかく使い方を見てみよう。

import datetime

yukari = "田村ゆかり"
age = 40
anniversary = datetime.date(1976, 2, 27)
print(f"{yukari}{age-23}歳: Anniv. {anniversary: %A, %B, %d, %Y}")

# 田村ゆかり17歳: Anniv.  Friday, February, 27, 1976

はい。*2

波カッコ{}の中に式を書けるようになっているということですね。これはそれなりに便利。

str.formatを使った同じことをするコードと比較してみましょう。かなり楽ちんにかけるようになったことがわかりますね!

print("{yukari}{age}歳: Anniv. {anniv: %A, %B, %d, %Y}".format(yukari=yukari, age=age-23, anniv=anniversary))

# 順番通りに出力するだけなら
# プレースホルダなしでこう書ける
print("{}{}歳: Anniv. {:%A, %B, %d, %Y}".format(yukari, age-23, anniversary))

f-stringsを使ってFizzBuzz

この記事書いたモチベーションがどこから来たのかというと、次のスレのワンライナーを見てちょっと興をそそられたから、というのがあります。

Reddit: a Py3.6 fizzBuzz oneliner with f-strings(はてなが馬鹿なのでリンク貼れません)

print(*map(lambda i: f"{'Fizz' * (not i%3)}{'Buzz' * (not i%5)}" or i, range(1,101)), sep='\n')

(f-stringsを使ったからと言ってFizzBuzz最短記録が出るわけでもないし、どうということはないのですが)

わかりやすく書き直すとこうです。

for i in range(1,101):
    fizz = "Fizz" if i%3==0 else ''
    buzz = "Buzz" if i%5==0 else ''
    print(f'{fizz}{buzz}' or i)

どちらのコードもcyberspacecowboy氏作。

なんか機能が出ると使いみちをすぐ見つける人がいるので感心した。

細かいこと

f-stringsはraw文字列と組み合わせて使うことができる。fr"ほにゃらら"という感じだ。いっぽうbyte文字列とは3.6の時点では組み合わせて使えないfb"ほにゃらら"。またユニコード文字列指定u(ご存知でしょうが、2.x系限定機能)とは一緒に使えない。f-stringsはpython 3.6の新機能であり、3系の新機能はpython 2.x系にはバックポートされないからだ。

ということを以下の記事を見ながらダラダラと書きました。

The new f-strings in Python 3.6 | Seasoned & Agile

この記事は他言語(js)との比較やpycharm連携がどうたらとかも書いてあり、また他のフォーマット手法とのパフォーマンスの比較もしていて、f-strings最速らしいです。わかんないけどためになるので見ておくといーよ☆ミ(ローラ風)

ちゃんとした仕様はPEP 498を読むのが一番早いんだけどだるいんでやりません。Rationaleには%によるフォーマットがint, str, doubleに対してしか動かないんでだるいとか、str.format()打つの長すぎてだるいとか、Templateはフォーマット形式を細かく指定できなくて使いづらいとか、そんな感じのことが書いてあると思います。

完全に蛇足

PyFormat: Using % and .format() for great good!

pythonistaは文字列フォーマットが好きなようで、上のようなサイトが結構需要があったりする。

f-stringsの解説も早く入るといいですね。

こちらからは以上です

*1:PEP20: There should be one-- and preferably only one--obvious way to do it.

*2:ネットスラングで知っている程度で声優ネタを使って申し訳ないと思っているが、あまり興味の引けそうな作文ができず最初に思いついたのがこれだったんです許してください…