it-swarm.com.de

f-Strings in Python 3.6

Ich gehe sehr gerne in den Code-Stil ein und es ist interessant zu wissen, ob es von nun an in allen Fällen besser wäre, den neuen Stil zu verwenden.

Ich benutze viel .format() in meinen Python 3.5-Projekten, und ich befürchte, dass es aufgrund dieser neuen Art von String-Literalen in den nächsten Python-Versionen verworfen wird. 

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

Ersetzt die formatierte Zeichenfolge die alte format() vollständig?

Ich verstehe, dass es auf der Idee basiert, dass: 

Einfach ist besser als komplex.

Was ist jedoch mit Leistungsproblemen, gibt es Unterschiede zwischen ihnen? Oder ist es nur ein einfacher Blick auf dieselbe Funktion?

28
nivhanin

Ich fürchte, dass es in den nächsten Python-Versionen nicht mehr verwendet wird

Seien Sie nicht, str.format erscheint nicht (und hat keinen Grund), um in Kürze zu gehen. Das PEP, das fprefixed-strings eingeführt hat, heißt sogar in seiner Zusammenfassung :

In diesem PEP wird nicht vorgeschlagen, die vorhandenen String-Formatierungsmechanismen zu entfernen oder abzulehnen.

Formatierte Zeichenfolgen wurden eingeführt, um einige der Nachteile zu beheben, die andere Methoden zum Formatieren von Zeichenfolgen hatten. Um die alten Methoden nicht wegzuwerfen und gottesfürchtig zu machen, wie viele Projekte F-Strings verwenden, wenn ihr Code für Python 3.6+ funktionieren soll.


Was die Leistung anbelangt, so scheint mir mein erster Verdacht, dass sie langsamer sein könnten, falsch. F-Strings scheinen ihre .format-Pendants leicht zu übertreffen:

➜ 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

Diese wurden zum Zeitpunkt des Schreibens gegen den Master-Zweig des CPython-Repositorys durchgeführt. Sie sind definitiv Änderungen unterworfen:

  • f-strings kann als neue Funktion möglicherweise optimiert werden 
  • Optimierungen in CPython können .format möglicherweise schneller machen (z. B. Speedup-Methodenaufrufe 1.2x ). 

Aber wirklich, machen Sie sich nicht so viel Gedanken über die Geschwindigkeit, sorgen Sie sich darum, was für Sie und für andere lesbarer ist.

In vielen Fällen wird dies f-strings sein, aber es gibt einige Fälle , in denen format besser ist. 

Um auf Jims Antwort aufzubauen und auf Ihr Leistungsproblem einzugehen, habe ich mit dem dis-Modul von python die Bytecode-Anweisungen für zwei syntaktisch verschiedene, aber funktional äquivalente Funktionen verglichen.

import dis

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

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

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

Das Ergebnis davon ist:

  11 0 LOAD_CONST 1 ('test') 
 2 STORE_FAST 0 (a) 

 12 4 LOAD_FAST 0 (a) 
 6 FORMAT_VALUE 0 
 8 RETURN_VALUE 
 Keine 
 15 0 LOAD_CONST 1 ('{a}') 
 2 LOAD_ATTR 0 (Format) 
 4 LOAD_CONST 2 ('test') 
 6 LOAD_CONST 3 (('a',)) 
 8 CALL_FUNCTION_KW 1 
 10 RETURN_VALUE 
 Keine

Man kann sehen, dass der F-String die Formatierung ohne Attribut- oder Funktionsaufrufe handhabt, was die Typüberprüfung und den Speicheraufwand verursachen kann. Laut timeit führt dies zu einer ungefähr dreifachen Leistungssteigerung (für meine spezifischen Funktionen).

>>> timeit.timeit ('f1 ()', 'from __main__ import f1', number = 100000) 
 0.012325852433775708 
 >>> timeit.timeit ('f2 ()', 'from __main__ import f2' Zahl = 100000). 0,036395029920726074
23
Aaron

Eine Sache, die nicht erwähnt wird (was eine Abwertung der alten Techniken unmöglich macht) ist, dass die Interpolation nur für String-Literale gilt. Das heißt, der String wird zur Laufzeit einmal gerendert. Die Vorlage kann nicht erneut mit aktualisierten Variablen verwendet werden. Beispiel:

str_template.format(args)

Ein anderer Fall ist i18n, wo string.Template verwendet wird. Viele Anwendungsfälle wären ohne die älteren Techniken nicht möglich. Genießen Sie die String-Interpolation, verwenden Sie sie jedoch nicht an Orten, an denen sie nicht geeignet ist, d. H. An Orten, an denen Sie eine wiederverwendbare Vorlage benötigen.

9
Gringo Suave

Wenn Sie weiterhin Python 3.5 unterstützen möchten, können Sie fstring verwenden.

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