Python 3のf-String:改善された文字列フォーマット構文(ガイド)

Python 3のf-String:改善された文字列フォーマット構文(ガイド)

Python 3.6の時点では、f-stringは文字列をフォーマットするための素晴らしい新しい方法です。 他のフォーマット方法よりも読みやすく、簡潔で、エラーが少ないだけでなく、高速です!

この記事の終わりまでに、今日からF文字列の使用を開始する方法と理由を学習します。

しかし、最初に、雪の中で両方の道を登って学校に行かなければならなかったとき、f-stringsの前の生活はどのようなものでしたか。

*無料のPDFダウンロード: *https://realpython.com/bonus/python-cheat-sheet-short/[Python 3 Cheat Sheet]

Pythonでの「昔ながらの」文字列フォーマット

Python 3.6より前には、書式設定のために文字列リテラル内にPython式を埋め込む2つの主な方法がありました:%-formattingと + str.format()+。 それらの使用方法とその制限を確認しようとしています。

オプション#1:%-formatting

これはPythonフォーマットのOGであり、最初から言語で使用されてきました。 詳細については、https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting [Python docs]をご覧ください。 次の注意事項が含まれているドキュメントでは、%書式設定は推奨されないことに注意してください。

_ _ 「ここで説明する書式設定操作には、多くの一般的なエラー(タプルや辞書を正しく表示できないなど)につながるさまざまな癖があります。

新しいフォーマットの文字列リテラルまたは `+ str.format()+`インターフェイスを使用すると、これらのエラーを回避できます。 これらの代替手段は、テキストをフォーマットするためのより強力で、柔軟で拡張可能なアプローチも提供します。」 (https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting [ソース]) _ _

%フォーマットの使用方法

文字列オブジェクトには、文字列のフォーマットに使用できる「%」演算子を使用した組み込み操作があります。 実際には次のようになります。

>>>

>>> name = "Eric"
>>> "Hello, %s." % name
'Hello, Eric.'

複数の変数を挿入するには、それらの変数のタプルを使用する必要があります。 その方法は次のとおりです。

>>>

>>> name = "Eric"
>>> age = 74
>>> "Hello, %s. You are %s." % (name, age)
'Hello Eric. You are 74.'
%-formattingが優れていない理由

上で見たコード例は十分に読みやすいです。 ただし、いくつかのパラメーターと長い文字列の使用を開始すると、コードはすぐに読みにくくなります。 物事はすでに少し厄介に見え始めています:

>>>

>>> first_name = "Eric"
>>> last_name = "Idle"
>>> age = 74
>>> profession = "comedian"
>>> affiliation = "Monty Python"
>>> "Hello, %s %s. You are %s. You are a %s. You were a member of %s." % (first_name, last_name, age, profession, affiliation)
'Hello, Eric Idle. You are 74. You are a comedian. You were a member of Monty Python.'

残念ながら、この種の書式設定は冗長であり、タプルや辞書を正しく表示しないなどのエラーにつながるため、あまり適していません。 幸いなことに、明るい日があります。

オプション#2:str.format()

この新しい仕事の方法はPython 2.6で導入されました。 詳細については、https://docs.python.org/3/library/stdtypes.html#str.format [Python docs]をご覧ください。

str.format()の使用方法

+ str.format()+`は%-formattingの改善です。 通常の関数呼び出し構文を使用し、https://www.python.org/dev/peps/pep-3101/#controlling-formatting-on-a-per-type-basis [+ format()+で拡張可能] `メソッド]文字列に変換されるオブジェクト。

`+ str.format()+`を使用すると、置換フィールドは中括弧でマークされます。

>>>

>>> "Hello, {}. You are {}.".format(name, age)
'Hello, Eric. You are 74.'

インデックスを参照することで、変数を任意の順序で参照できます。

>>>

>>> "Hello, {1}. You are {0}.".format(age, name)
'Hello, Eric. You are 74.'

しかし、変数名を挿入すると、オブジェクトを渡すことができ、その後に括弧と括弧で囲まれたパラメーターとメソッドを参照できるという追加の特典が得られます。

>>>

>>> person = {'name': 'Eric', 'age': 74}
>>> "Hello, {name}. You are {age}.".format(name=person['name'], age=person['age'])
'Hello, Eric. You are 74.'

また、 `+* * +`を使用して、辞書でこの巧妙なトリックを行うこともできます。

>>>

>>> person = {'name': 'Eric', 'age': 74}
>>> "Hello, {name}. You are {age}.".format(**person)
'Hello, Eric. You are 74.'

`+ str.format()+`は、%-formattingと比較した場合、間違いなくアップグレードですが、すべてがバラや太陽の光ではありません。

str.format()が優れていない理由

`+ str.format()`を使用したコードは%-formattingを使用したコードよりもはるかに読みやすくなっていますが、複数のパラメーターと長い文字列を扱う場合、 ` str.format()+`は依然として非常に冗長です。 これをみて:

>>>

>>> first_name = "Eric"
>>> last_name = "Idle"
>>> age = 74
>>> profession = "comedian"
>>> affiliation = "Monty Python"
>>> print(("Hello, {first_name} {last_name}. You are {age}. " +
>>>        "You are a {profession}. You were a member of {affiliation}.") \
>>>        .format(first_name=first_name, last_name=last_name, age=age, \
>>>                profession=profession, affiliation=affiliation))
'Hello, Eric Idle. You are 74. You are a comedian. You were a member of Monty Python.'

辞書で `+ .format()`に渡したい変数がある場合は、 ` .format(* *some_dict)+`でそれを展開し、文字列のキーで値を参照できます。しかし、これを行うにはより良い方法が必要です。

f-Strings:Pythonで文字列をフォーマットする新しい改善された方法

良いニュースは、f文字列が1日を節約するためにここにあるということです。 彼らはスライス! 彼らはサイコロ! 彼らは千切りフライを作ります! わかりました、それらはそれらのどれもしませんが、フォーマットをより簡単にします。 彼らはPython 3.6でパーティーに参加しました。 Eric Vによって書かれたhttps://www.python.org/dev/peps/pep-0498/[PEP 498]でそれに関するすべてを読むことができます。 2015年8月のスミス。

「フォーマットされた文字列リテラル」とも呼ばれるf文字列は、先頭に `+ f `があり、値で置き換えられる式を含む中括弧がある文字列リテラルです。 式は実行時に評価され、 ` format +`プロトコルを使用してフォーマットされます。 いつものように、https://docs.python.org/3/reference/lexical_analysis.html#f-strings [Python docs]は、詳細を知りたいときの友達です。

以下は、f-stringsがあなたの人生を楽にする方法のいくつかです。

簡単な構文

構文は、 `+ str.format()+`で使用したものと似ていますが、冗長ではありません。 これがどれほど簡単に読めるかを見てください。

>>>

>>> name = "Eric"
>>> age = 74
>>> f"Hello, {name}. You are {age}."
'Hello, Eric. You are 74.'

大文字の `+ F +`を使用することも有効です。

>>>

>>> F"Hello, {name}. You are {age}."
'Hello, Eric. You are 74.'

あなたはまだf弦が好きですか? この記事の終わりまでに、https://twitter.com/dbader_org/status/992847368440561664 [+ >>> F" Yes! "+]に回答していただければ幸いです。

任意の表現

f文字列は実行時に評価されるため、有効なPython式をすべて含めることができます。 これにより、気の利いたことができます。

次のように、非常に簡単なことができます。

>>>

>>> f"{2* 37}"
'74'

ただし、関数を呼び出すこともできます。 例を示しましょう。

>>>

>>> def to_lowercase(input):
...     return input.lower()

>>> name = "Eric Idle"
>>> f"{to_lowercase(name)} is funny."
'eric idle is funny.'

メソッドを直接呼び出すオプションもあります。

>>>

>>> f"{name.lower()} is funny."
'eric idle is funny.'

F文字列を持つクラスから作成されたオブジェクトを使用することもできます。 次のクラスがあると想像してください。

class Comedian:
    def __init__(self, first_name, last_name, age):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age

    def __str__(self):
        return f"{self.first_name} {self.last_name} is {self.age}."

    def __repr__(self):
        return f"{self.first_name} {self.last_name} is {self.age}. Surprise!"

あなたはこれを行うことができるでしょう:

>>>

>>> new_comedian = Comedian("Eric", "Idle", "74")
>>> f"{new_comedian}"
'Eric Idle is 74.'

https://realpython.com/operator-function-overloading/[`+ str()`および ` repr ()`メソッド]は、オブジェクトが文字列としてどのように提示されるかを処理するため、確認する必要がありますこれらのメソッドの少なくとも1つをクラス定義に含めます。 1つを選択する必要がある場合は、「 str ()」の代わりに使用できるため、「 repr ()+」を使用します。

`+ str ()`によって返される文字列は、オブジェクトの略式の文字列表現であり、読み取り可能である必要があります。 ` repr ()`によって返される文字列は公式の表現であり、明確でなければなりません。 ` str ()`と ` repr ()`を直接使用するよりも、 ` str()`と ` repr()+`を呼び出す方が望ましいです。

デフォルトでは、f-stringsは `+ str ()`を使用しますが、変換フラグ `!r `を含めると、必ず ` repr ()+`を使用できます。

>>>

>>> f"{new_comedian}"
'Eric Idle is 74.'
>>> f"{new_comedian!r}"
'Eric Idle is 74. Surprise!'

完全なPython式をサポートするf文字列になった会話の一部を読みたい場合は、https://mail.python.org/pipermail/python-ideas/2015-July/034726.html [ここに]。

複数行のf文字列

複数行の文字列を使用できます。

>>>

>>> name = "Eric"
>>> profession = "comedian"
>>> affiliation = "Monty Python"
>>> message = (
...     f"Hi {name}. "
...     f"You are a {profession}. "
...     f"You were in {affiliation}."
... )
>>> message
'Hi Eric. You are a comedian. You were in Monty Python.'

しかし、複数行の文字列の各行の前に「+ f +」を配置する必要があることを忘れないでください。 次のコードは機能しません。

>>>

>>> message = (
...     f"Hi {name}. "
...     "You are a {profession}. "
...     "You were in {affiliation}."
... )
>>> message
'Hi Eric. You are a {profession}. You were in {affiliation}.'

個々の行の前に「+ f +」を付けない場合、通常の古い庭の種類の文字列があり、光沢のある新しい派手なf文字列はありません。

文字列を複数行に広げたい場合は、 `+ \ +`でリターンをエスケープするオプションもあります:

>>>

>>> message = f"Hi {name}. " \
...           f"You are a {profession}. " \
...           f"You were in {affiliation}."
...
>>> message
'Hi Eric. You are a comedian. You were in Monty Python.'

しかし、これは `+" "" + `を使用した場合に起こることです:

>>>

>>> message = f"""
...     Hi {name}.
...     You are a {profession}.
...     You were in {affiliation}.
... """
...
>>> message
'\n    Hi Eric.\n    You are a comedian.\n    You were in Monty Python.\n'

PEP 8のインデントガイドラインを参照してください。

速度

f-stringsの `+ f +`は、「高速」の略です。

f-stringsは%-formattingと `+ str.format()+`の両方よりも高速です。 既に見たように、f-stringは定数値ではなく、実行時に評価される式です。 ドキュメントからの抜粋は次のとおりです。

_ 「F文字列は、最小限の構文を使用して、文字列リテラル内に式を埋め込む方法を提供します。 f文字列は実際には実行時に評価される式であり、定数値ではないことに注意してください。 Pythonソースコードでは、f-stringはリテラル文字列であり、先頭に `+ f +`が付き、中括弧内に式が含まれます。 式は値に置き換えられます。」 (https://www.python.org/dev/peps/pep-0498/#abstract [ソース]) _

実行時に、中括弧内の式は独自のスコープで評価され、f-stringの文字列リテラル部分と一緒になります。 結果の文字列が返されます。 それだけです。

速度の比較は次のとおりです。

>>>

>>> import timeit
>>> timeit.timeit("""name = "Eric"
... age = 74
... '%s is %s.' % (name, age)""", number = 10000)
0.003324444866599663

>>>

>>> timeit.timeit("""name = "Eric"
... age = 74
... '{} is {}.'.format(name, age)""", number = 10000)
0.004242089427570761

>>>

>>> timeit.timeit("""name = "Eric"
... age = 74
... f'{name} is {age}.'""", number = 10000)
0.0024820892040722242

ご覧のとおり、fストリングが上に出ています。

ただし、常にそうとは限りませんでした。 それらが最初に実装されたとき、いくつかのhttps://stackoverflow.com/questions/37365311/why-are-literal-formatted-strings-so-slow-in-python-3-6-alpha-now-fixed-inがありました-3-6 [速度の問題]で、 + str.format()+`よりも高速にする必要がありました。 特別なhttps://bugs.python.org/issue27078 [+ BUILD_STRING +` opcode]が導入されました。

Python f-ストリング:厄介な詳細

f-stringsが優れている理由をすべて理解できたので、f-stringsを使用して使い始めたいと思います。 この勇敢な新しい世界に挑戦する際に留意すべきいくつかの詳細を以下に示します。

引用符

式内でさまざまなタイプの引用符を使用できます。 式で使用しているのと同じタイプの引用符をf-stringの外側で使用していないことを確認してください。

このコードは動作します。

>>>

>>> f"{'Eric Idle'}"
'Eric Idle'

このコードも動作します:

>>>

>>> f'{"Eric Idle"}'
'Eric Idle'

三重引用符も使用できます。

>>>

>>> f"""Eric Idle"""
'Eric Idle'

>>>

>>> f'''Eric Idle'''
'Eric Idle'

文字列の内側と外側の両方で同じタイプの引用符を使用する必要がある場合、 `+ \ +`でエスケープできます。

>>>

>>> f"The \"comedian\" is {name}, aged {age}."
'The "comedian" is Eric Idle, aged 74.'

辞書

引用符といえば、辞書で作業しているときは注意してください。 辞書のキーに一重引用符を使用する場合は、キーを含むf文字列に二重引用符を使用していることを忘れないでください。

これは動作します:

>>>

>>> comedian = {'name': 'Eric Idle', 'age': 74}
>>> f"The comedian is {comedian['name']}, aged {comedian['age']}."
The comedian is Eric Idle, aged 74.

しかし、これは構文エラーを伴う大混乱になります。

>>>

>>> comedian = {'name': 'Eric Idle', 'age': 74}
>>> f'The comedian is {comedian['name']}, aged {comedian['age']}.'
  File "<stdin>", line 1
    f'The comedian is {comedian['name']}, aged {comedian['age']}.'
                                    ^
SyntaxError: invalid syntax

f-stringの外側で使用するのと同じタイプのクォーテーションマークをディクショナリキーの周りで使用する場合、最初のディクショナリキーの先頭のクォーテーションマークは文字列の終わりとして解釈されます。

中括弧

文字列に中括弧を表示するには、二重中括弧を使用する必要があります。

>>>

>>> f"{{74}}"
'{74}'

トリプルブレースを使用すると、ストリング内にシングルブレースのみが存在することに注意してください。

>>>

>>> f"{{{74}}}"
'{74}'

ただし、3つ以上のブレースを使用する場合は、表示するブレースを増やすことができます。

>>>

>>> f"{{{{74}}}}"
'{{74}}'

バックスラッシュ

前に見たように、f文字列の文字列部分でバックスラッシュエスケープを使用することができます。 ただし、バックスラッシュを使用してf文字列の式部分でエスケープすることはできません。

>>>

>>> f"{\"Eric Idle\"}"
  File "<stdin>", line 1
    f"{\"Eric Idle\"}"
                      ^
SyntaxError: f-string expression part cannot include a backslash

事前に式を評価し、結果をf文字列で使用することで、この問題を回避できます。

>>>

>>> name = "Eric Idle"
>>> f"{name}"
'Eric Idle'

式には、「#」記号を使用したコメントを含めないでください。 構文エラーが表示されます:

>>>

>>> f"Eric is {2 *37 #Oh my!}."
  File "<stdin>", line 1
    f"Eric is {2* 37 #Oh my!}."
                                ^
SyntaxError: f-string expression part cannot include '#'

フォースアンドフォーマット!

文字列をフォーマットする古い方法を引き続き使用できますが、f文字列を使用すると、より簡潔で読みやすく、便利で、より高速でエラーが発生しにくい方法を使用できます。 f-stringsを使用して生活を簡素化することは、まだ切り替えを行っていない場合にPython 3.6を使い始める大きな理由です。 (まだPython 2を使用している場合は、https://pythonclock.org/[2020]が間もなく公開されることを忘れないでください!)

Zen of Pythonによると、何かをする方法を決める必要があるときは、「[t] here should one-and好ましくはonly一つ-それを行う明白な方法。」文字列をフォーマットするための可能な方法はf文字列だけではありませんが、f文字列は仕事を成し遂げるための1つの明白な方法になる絶好の位置にあります。

参考文献

文字列の補間に関する詳細な説明をご覧になりたい場合は、https://www.python.org/dev/peps/pep-0502/[PEP 502]をご覧ください。 また、https://www.python.org/dev/peps/pep-0536/[PEP 536 draft]には、f-stringの将来についてのいくつかの考えがあります。

無料のPDFダウンロード: Python 3 Cheat Sheet

文字列をさらに楽しむには、次の記事をご覧ください。

ハッピーパイソン!