Pythonの文字列フォーマットの多くの方法—古いもの(廃止予定)は非推奨ですか?


106

Pythonには、少なくとも6つの文字列フォーマット方法があります。

In [1]: world = "Earth"

# method 1a
In [2]: "Hello, %s" % world
Out[2]: 'Hello, Earth'

# method 1b
In [3]: "Hello, %(planet)s" % {"planet": world}
Out[3]: 'Hello, Earth'

# method 2a
In [4]: "Hello, {0}".format(world)
Out[4]: 'Hello, Earth'

# method 2b
In [5]: "Hello, {planet}".format(planet=world)
Out[5]: 'Hello, Earth'

# method 2c
In [6]: f"Hello, {world}"
Out[6]: 'Hello, Earth'

In [7]: from string import Template

# method 3
In [8]: Template("Hello, $planet").substitute(planet=world)
Out[8]: 'Hello, Earth'

さまざまな方法の簡単な履歴:

  • printfスタイルのフォーマットは、Pythonの初期の頃からありました
  • このTemplateクラスはPython 2.4で導入されました
  • このformatメソッドはPython 2.6で導入されました
  • f-stringsはPython 3.6で導入されました

私の質問は:

  • されたprintfスタイルの書式設定は、非推奨または廃止されるになるだろうか?
  • ではTemplate class、あるsubstitute方法は非推奨または廃止されるになるだろうか?(私はについて話していないsafe_substitute、それは理解しているようにそれがユニークな機能を提供する)

同様の質問と、それらが重複していないと思う理由:

こちらもご覧ください


1
Formatterクラスを忘れたことを指摘する必要がありますか?
Martijn Pieters

回答:


14

ドキュメントには.format、f文字列が文字列よりも優れているというさまざまな指摘がありますが%、後者を廃止する計画は残っていません。

コミット問題#14123で:古いスタイルの%文字列の書式設定には注意が必要ですが、すぐにはなくなることはないことを明確に述べてください。、問題に触発され printfスタイルのフォーマットを廃止する予定は現在ないことを示し、% -formattingのドキュメントを次のフレーズを含むように編集しました。

新しい文字列フォーマット構文はより柔軟で、タプルと辞書を自然に処理するため、新しいコードに推奨されます。しかしながら、現在のところ、printfスタイルのフォーマットを廃止する計画はありません

(エンファシス鉱山。)

このフレーズは、コミットクローズ#4966で後で削除されました。最新のPythonの状態をより詳しく説明するために、シーケンスドキュメントを改訂しました。これは、%フォーマットを廃止する計画がカードに戻ったという兆候のように思えるかもしれませんが、バグトラッカーを詳しく調べると、その意図が逆であることがわかります。バグトラッカーでは、コミットの作成者が変更を次のように特徴付けています。

  • printfスタイルのフォーマットとstr.formatメソッドの関係を説明する散文を変更しました(前者が消えるという本当の危険性であるという意図を意図的に削除します-完全に削除することを真剣に考えるのは実際的ではありません)

つまり、%-formattingのドキュメントに2つの連続した変更が加えられており、廃止されることはもちろん、廃止されないことを明示的に強調することを目的とています。ドキュメントは、さまざまな種類の文字列フォーマットの相対的なメリットについて意見が分かれていますが、-formattingが非推奨になったり削除されたりしないことも明らかです。%

さらに、2017年3月にその段落加えられた最新の変更により、この段落から変更されました...

ここで説明するフォーマット操作は、多くの一般的なエラー(タプルや辞書を正しく表示できないなど)につながるさまざまな癖を示します。新しいフォーマットの文字列リテラルまたはstr.formatインターフェイスを使用すると、これらのエラーを回避できます。これらの代替手段は、テキストをフォーマットするためのより強力で柔軟で拡張可能なアプローチも提供します。

...これに:

ここで説明するフォーマット操作は、多くの一般的なエラー(タプルや辞書を正しく表示できないなど)につながるさまざまな癖を示します。新しいフォーマットの文字列リテラル、str.formatインターフェース、またはテンプレート文字列を使用すると、これらのエラーを回避できる場合があります。これらの代替案はそれぞれ、独自のトレードオフと、シンプルさ、柔軟性、および/または拡張性の利点を提供します。

「回避するのに役立つ」から「回避するのに役立つ」への変更、.formatおよびfストリングの明確な推奨がどのように各スタイルが「独自のトレードオフと利点を提供する」かについてのふわふわで曖昧な散文にどのように置き換えられたかに注目してください。つまり、カードが正式に廃止されなくなっただけでなく、現在のドキュメントでは、%フォーマットが少なくとも他のアプローチよりも「利点」があることを公然と認めています。

これらすべてから、%書式設定を非推奨または削除する動きが妨げられただけでなく、完全かつ永久に打ち負かされたと推測します。


2
Mercurialのコードベースが大きすぎての使用を根絶できずにMercurialが置き去りにされることを望まないMercurialのメンテナをなだめるために、ふわふわした言語の変更が追加されました%。「大規模なコードの改造は行わない」というポリシーは廃止されたため、彼らの反対も薄れてきています。長期的には、両方のフォームを維持し、いずれ% かの時点で利点が残っていないため、printf構文はいずれにせよ削除されます。私たちはまだいつかわからないので、その言語は調整する価値がありました。
Martijn Pieters

@MartijnPieters興味深い。私が欠けているこの決定についてあなたはかなりの知識を持っているようです。価値のあるものについては、これらのポイントを概説するよく参照された回答(新しい回答または既存の回答の編集)が価値があると思います。
Mark Amery

58

新しい.format()メソッドは、古い%フォーマット構文を置き換えることを目的としています。後者は強調されてませ(ただし、まだ非推奨ではありませ)。メソッドのドキュメントには、次のように記載されています。

この文字列フォーマットの方法は、Python 3の新しい標準であり、新しいコードの文字列フォーマット操作で説明されているフォーマットよりも推奨%されます。

(エンファシス鉱山)。

下位互換性を維持し、移行を容易にするために、今のところ古い形式が残されています。元のPEP 3101提案から

下位互換性

既存のメカニズムをそのままにしておくことで、下位互換性を維持できます。新しいシステムは、既存の文字列フォーマット手法のメソッド名と衝突しないため、古いシステムを廃止するまで、両方のシステムを共存させることができます。

古いシステムを廃止する時が来るまで注意してください。これは廃止されていませんが、新しいコードを記述するときは常に新しいシステムが使用されます

新しいシステムには、古いフォーマッターのタプルと辞書のアプローチを組み合わせることができるという利点があります%

"{greeting}, {0}".format(world, greeting='Hello')

object.__format__()個々の値のフォーマットを処理するために使用されるフックを介して拡張可能です。

古いシステムには%Templateクラスがあり、後者ではその動作を追加または変更するサブクラスを作成できることに注意してください。新しいスタイルのシステムには、同じニッチを満たすFormatterクラスがあります。

Python 3は非推奨からさらに一歩進んで、代わりにprintf-style String Formattingセクションで警告を出します:

:ここで説明するフォーマット操作は、多くの一般的なエラー(タプルや辞書を正しく表示できないなど)につながるさまざまな癖を示します。新しいフォーマットの文字列リテラルまたはstr.format()インターフェイスを使用すると、これらのエラーを回避できます。これらの代替手段は、テキストをフォーマットするためのより強力で柔軟で拡張可能なアプローチも提供します。

Python 3.6 では、フォーマットされた文字列リテラルも追加れました。これは、式フォーマット文字列にインラインします。これらは、補間された値で文字列を作成する最も速い方法でありstr.format()、リテラルを使用できる場所ではなく、使用する必要があります。


4
またFormatterdatetimeオブジェクトで使用するようなカスタム形式を作成できます。また、.formatは関数であるため、これを使用して呼び出し可能な遅延フォーマットをより直接作成できます。例:fmt = '{} - {}'.format; fmt(a, b)
Jon Clements

古いシステムとどのようTemplateに関連しているかはわかりません。特に、リンクするPEP は、この提案との間にはある程度の重複がありますが、それぞれが明確なニーズに対応しており、一方が他方を未然に防いでいるように感じられます。あなたの答えでは、古いシステムの一部であるフォーマットも非推奨であると混乱するかもしれません。%string.TemplateTemplate
Bakuriu 2013

@Bakuriu:そうですね、その部分を逃したと思います。しかし、私の意見では、Formatterクラスはと同じニーズを満たすことができますstring.Template()
Martijn Pieters

1
[...]should be preferred to the % formatting[...]この部分はドキュメントから削除されました。docs.python.org/3/library/stdtypes.html#str.format
AXO

この答えは現在誤解を招くと思います。引用された最初のパッセージはPython 3のドキュメントから削除されており、廃止が行われる意図が残っていないことは私にはかなり明白に思われます。この回答にはまだ歴史的な価値がありますが、カードに非推奨がまだ残っているという提案を避け、回答の前半の大部分を過去形に編集するために、文言を微調整する傾向があります。異議がなければ、いつか自分でそうするつもりですが、必要に応じて自分でそのような変更を加える機会を与えるために最初にコメントしたいと思いました。
Mark Amery

45

%文字列フォーマットの演算子は廃止されておらず、他の回答にもかかわらず、削除されることはありません。
主題がPython開発リストで取り上げられるたびに、どちらが良いかについて強い論争がありますが、古典的な方法を削除するかどうかについては論争がありません。PEP 3101に記載されているにもかかわらず、Python 3.1が登場し、姿を消しました。%消しました。

クラシックなスタイルを維持するためのステートメントは明確です。シンプルで、高速で、短いことをすばやく実行できます。この.formatメソッドを使用すると、常に読みやすくなるとは限りません。また、コア開発者の間でも、ほとんど誰もが.format、リファレンスを参照しなくても提供される完全な構文を使用できます。2009年にも、次のようなメッセージが表示されました。 python.org/pipermail/python-dev/2009-October/092529.html 、件名はほとんどリストに表示されませんでした。

2016年更新

現在のPython開発バージョン(Python 3.6になる)には、PEP-0498で説明されている文字列補間の3番目の方法があります。これは、新しい引用プレフィックスを定義するf""(現在ほかにu""b""r"")。

文字列に接頭辞を付けると、f実行時に文字列オブジェクトのメソッドが呼び出され、現在のスコープから文字列に変数が自動的に補間されます。

>>> value = 80
>>> f'The value is {value}.'
'The value is 80.'

3
型が独自のを実装できるようにする方がはるかに優れてい__format__ます。たとえば、format(Decimal('0.1'), '.20f')vs '%.20f' % Decimal('0.1')。後者はDecimalをfloatに強制変換します。
Eryk Sun、2012

2
NB。古いスタイルの方がすべての点で優れていると私は主張しませんでした。ただ、それが短く、読みやすくなる場合もあります(そうでない場合もあります)。確かに、新しい方法ははるかに柔軟です。
jsbueno 2015

fPython 3に相当するものはありますか?
Daniel

上記f-stringsで使用されているは、Python 3.6以降の言語の新機能です。これは以前のバージョンには存在せず、それらの構文エラーが発生します。
jsbueno

20

これに関するグイドの最新の位置がここに示されているようです:

Python 3.0の新機能

PEP 3101:文字列フォーマットへの新しいアプローチ

組み込みの文字列フォーマット操作用の新しいシステムは、%文字列フォーマット演算子を置き換えます。(ただし、%演算子は引き続きサポートされています。Python3.1で非推奨になり、しばらくして言語から削除されます。)完全な概要については、PEP 3101をお読みください。

そして、最後に変更されたのは(2011年9月30日金)のPEP3101自体なので、その時点での進展はないと思います。


18

古いPythonドキュメントとPEP 3101を見ると、%演算子は非推奨になり、将来言語から削除されるという声明がありました。次の文は Pythonの3.0、3.1、および3.2用のPythonのドキュメントにありました:

str.format()はかなり新しいので、多くのPythonコードはまだ%演算子を使用しています。ただし、この古いスタイルのフォーマットは最終的に言語から削除されるため、通常はstr.format()を使用する必要があります。

Python 3.3と3.4のドキュメントの同じセクションに移動すると、そのステートメントが削除されていることがわかります。また、演算子が非推奨になるか、言語から削除されることを示す他のステートメントをドキュメントのどこにも見つけることができません。PEP3101が2年半以上変更されていないことにも注意することが重要です(金、2011年9月30日)。

更新

PEP461バイトおよびバイト配列に%書式を追加することは受け入れられ、Python 3.5または3.6の一部である必要があります。これは、%演算子が生きていて蹴っているという別の兆候です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.