web-dev-qa-db-ja.com

高度な文字列フォーマットとテンプレート文字列

新しい 高度な文字列フォーマット ?の代わりに テンプレート文字列 を使用する利点があるかどうか疑問に思っていました。

42
P3trus

テンプレートは、表現力を犠牲にして、通常の文字列の書式設定よりも単純であることを意図しています。 PEP 292 の理論的根拠は、テンプレートをPythonの%- style文字列フォーマットと比較します:

Pythonは現在、Cのprintf() '%'フォーマット文字に基づく文字列置換構文をサポートしています。豊富な%フォーマットコードは、経験のあるPythonプログラマでも。エラーが発生しやすい。よくある間違いは、%(name)ssなど、末尾のフォーマット文字を省くことです。

さらに、%記号の後に続くルールはかなり複雑ですが、通常のアプリケーションではこのような複雑さはほとんど必要ありません。ほとんどのスクリプトは何らかの文字列補間を行う必要がありますが、それらのほとんどは単純なstringification' formats, i.e.%sor%(name)s`を使用します。

新しい.format()は状況を改善しましたが、 format string syntax がかなり複雑であるため、理論的根拠にはまだポイントがあります。

20
Sven Marnach

それが価値があるのは、辞書のテンプレート置換は、テンプレートの長さに応じて、フォーマット置換よりも4〜10倍遅いようです。以下は、Python 3.5。

from string import Template
lorem = "Lorem ipsum dolor sit amet {GIBBERISH}, consectetur adipiscing elit {DRIVEL}. Expectoque quid ad id, quod quaerebam, respondeas."
loremtpl = Template("Lorem ipsum dolor sit amet $GIBBERISH, consectetur adipiscing elit $DRIVEL. Expectoque quid ad id, quod quaerebam, respondeas.")
d = dict(GIBBERISH='FOOBAR', DRIVEL = 'RAXOOP')

In [29]: timeit lorem.format(**d)
1.07 µs ± 2.13 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [30]: timeit loremtpl.substitute(d)
8.74 µs ± 12.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

私がテストした最悪のケースは、13文字の文字列で約10倍遅くなりました。私がテストした最高のケースは、71000文字の文字列の約4倍の速度でした。

11
Mike Ellis

文字列テンプレートの主な利点の1つは、safe_substitutemethod を使用して、プレースホルダーのsomeのみを置換できることです。プレースホルダーに値が渡されない場合、通常のフォーマット文字列ではエラーが発生します。例えば:

"Hello, {first} {last}".format(first='Joe')

を発生させます:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'last'

だが:

from string import Template
Template("Hello, $first $last").safe_substitute(first='Joe')

生産物:

'Hello, Joe $last'

戻り値はTemplateではなく文字列であることに注意してください。 $lastを置き換える場合は、その文字列から新しいTemplateオブジェクトを作成する必要があります。

6
bwk

これは主に構文の優先順位の問題であり、通常は、怠//冗長性のトレードオフと、既存の文字列テンプレートシステムの習熟/習慣に要約されます。この場合、テンプレート文字列は書くのが面倒/単純/速いのですが、.format()はより冗長で機能が充実しています。

PHP言語またはテンプレートシステムのJinjaファミリに慣れているプログラマは、テンプレート文字列を好むかもしれません。 "%s"位置スタイルを使用するタプル置換は、printf- likeを使用する人にアピールするかもしれません.format()にはさらにいくつかの機能がありますが、.format()だけが提供する特定の何かが必要でない限り、既存のスキームを使用しても何も問題はありません。

唯一注意すべきことは、名前付き文字列テンプレートの方が順序依存テンプレートよりも柔軟性が高く、メンテナンスの必要性が少ないことです。それ以外は、個人的な好みか、作業中のプロジェクトのコーディング標準のいずれかになります。

2
Preet Kukreti