web-dev-qa-db-ja.com

Python 3.6のf-strings

私はコードスタイルを深く掘り下げたいので、これからすべての場合に新しいスタイルを使用する方が良いかどうかを知るのは興味深いです。

私はPython 3.5プロジェクトで.format()を多く使用していますが、このため次のPythonバージョンで非推奨になると思います新しい種類の文字列リテラル。

_>>> name = "Test"
>>> f"My app name is {name}."
'My app name is Test.'
_

フォーマットされた文字列機能は、古いformat()を完全に置き換えますか?

私はそれが次のような考えに基づいていることを理解しています:

単純なものは複雑なものよりも優れています。

しかし、パフォーマンスの問題についてはどうですか、それらの間に違いはありますか?それとも、同じ機能の単純な外観ですか?

34
nivhanin

次の期間中に廃止されるのではないかと思うPythonバージョン

しないでください、str.formatは、すぐに出る予定はありません(また、理由もありません)、fprefixed-stringsを導入したPEPは、Abstractに 状態でもあります

このPEPは、既存の文字列フォーマットメカニズムを削除または廃止することを提案していません。

書式設定された文字列は、文字列を書式設定する他の方法の欠点のいくつかに対処するために導入されました。古いメソッドを捨てず、Python 3.6+。


これらのパフォーマンスに関しては、それらがより遅いかもしれないという私の最初の疑いは間違っているようです、f-stringsは_.formatカウンターパート:

➜ cpython git:(master) ./python -m timeit -s "a = 'test'" "f'formatting a string {a}'"
500000 loops, best of 5: 628 nsec per loop
➜ cpython git:(master) ./python -m timeit "'formatting a string {a}'.format(a='test')"
100000 loops, best of 5: 2.03 usec per loop

これらは、この記事の執筆時点でCPythonリポジトリのmasterブランチに対して行われました。それらは間違いなく変更される可能性があります。

しかし、実際には、速度についてはそれほど心配せず、あなたや他の人にとって読みやすいものを心配してください。

多くの場合、それはf-strings、しかし いくつかのケースがあります ここでformatの方が良いです。

Jimの答えに基づいてパフォーマンスの問題に対処するために、Pythonのdisモジュールを使用して、構文的には異なるが機能的には同等の2つの関数のバイトコード命令を比較しました。

import dis

def f1():
    a = "test"
    return f"{a}"

def f2():
    return "{a}".format(a='test')

print(dis.dis(f1))
print(dis.dis(f2))

結果は次のとおりです。

 11 0 LOAD_CONST 1( 'test')
 2 STORE_FAST 0(a)
 
 12 4 LOAD_FAST 0(a)
 6 FORMAT_VALUE 0 
 8 RETURN_VALUE 
なし
 15 0 LOAD_CONST 1( '{a}')
 2 LOAD_ATTR 0(フォーマット)
 4 LOAD_CONST 2( 'test')
 6 LOAD_CONST 3(( 'a'、))
 8 CALL_FUNCTION_KW 1 
 10 RETURN_VALUE 
なし

F文字列が属性または関数呼び出しなしでフォーマットを処理していることがわかります。これにより、型チェックとメモリオーバーヘッドが発生する可能性があります。 timeitによると、これによりパフォーマンスが約3倍になります(特定の機能に対して)。

>>> timeit.timeit( 'f1()'、 'from __main__ import f1'、number = 100000)
 0.012325852433775708 
 >>> timeit.timeit( 'f2()'、 'from __main__ import f2 '、number = 100000)
 0.036395029920726074
23
Aaron

言及されていないことの1つは(古い手法の廃止が不可能になることです)、補間は文字列リテラル専用です。つまり、文字列は実行時に一度レンダリングされます。テンプレートは、更新された変数で再度使用することはできません。例:

str_template.format(args)

別のケースは、string.Templateが使用されるi18nです。多くのユースケースは、古い技術なしでは不可能です。文字列の補間をお楽しみください。ただし、不適切な場所、つまり再利用可能なテンプレートが必要な場所では使用しないでください。

9
Gringo Suave

python 3.5をサポートし続けたい場合は、fstringを使用できます

pip install fstring

from fstring import fstring

x = 1

y = 2.0

plus_result = "3.0"

print fstring("{x}+{y}={plus_result}")

# Prints: 1+2.0=3.0
1
RinSlow