Pythons viele Möglichkeiten zur Formatierung von Zeichenfolgen - werden die älteren (werden) veraltet sein?

106

Python bietet mindestens sechs Möglichkeiten zum Formatieren eines Strings:

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'

Eine kurze Geschichte der verschiedenen Methoden:

  • printfFormatierung im Stil gibt es seit Pythons Kindheit
  • Die TemplateKlasse wurde in Python 2.4 eingeführt
  • Die formatMethode wurde in Python 2.6 eingeführt
  • f-strings wurden in Python 3.6 eingeführt

Meine Fragen sind:

  • Ist die printfFormatierung im Stil veraltet oder wird sie veraltet sein?
  • In der Template classist die substituteMethode veraltet oder veraltet gehen werden? (Ich spreche nicht darüber safe_substitute, was meines Wissens einzigartige Fähigkeiten bietet)

Ähnliche Fragen und warum ich denke, dass sie keine Duplikate sind:

Siehe auch

gerrit
quelle
1
Muss ich darauf hinweisen, dass Sie den FormatterUnterricht vergessen haben ?
Martijn Pieters

Antworten:

14

Während es in den Dokumenten verschiedene Hinweise gibt, dass .formatund F-Strings Strings überlegen sind %, gibt es keinen Überlebensplan, um Letzteres jemals zu verwerfen.

In Commit- Problem Nr. 14123: Erwähnen Sie ausdrücklich, dass die% -String-Formatierung im alten Stil Vorbehalte aufweist, aber nicht so schnell verschwindet. Durch Ausgabe, inspiriert zeigen , dass es keine aktuellen Pläne deprecate printf-Stil sind die Formatierung , die Dokumentation auf %-Formatieren bearbeitet wurden diese Phrase enthalten:

Da die neue Syntax für die Formatierung von Zeichenfolgen flexibler ist und Tupel und Wörterbücher auf natürliche Weise verarbeitet, wird sie für neuen Code empfohlen. Derzeit gibt es jedoch keine Pläne, die Formatierung im printf-Stil zu verwerfen .

(Hervorhebung von mir.)

Dieser Satz wurde später in Commit Close # 4966 entfernt: Überarbeiten Sie die Sequenzdokumente, um den Status des modernen Python besser zu erklären . Dies mag wie ein Zeichen dafür erscheinen, dass ein Plan, die %Formatierung zu verwerfen, wieder auf den Karten stand ... aber das Eintauchen in den Bug-Tracker zeigt, dass die Absicht das Gegenteil war. Auf dem Bug - Tracker, der Autor der Commit charakterisiert die Änderung wie folgt aus :

  • Die Prosa, die die Beziehung zwischen der Formatierung im printf-Stil und der str.format-Methode beschreibt, wurde geändert (absichtlich wurde die Implikation beseitigt, dass erstere eine echte Gefahr des Verschwindens darstellt - es ist einfach nicht praktikabel, ernsthaft darüber nachzudenken, sie zu töten).

Mit anderen Worten, wir haben zwei aufeinanderfolgende Änderungen an den %Formatierungsdokumenten vorgenommen, um ausdrücklich zu betonen, dass sie nicht veraltet oder gar entfernt werden. Die Dokumente sind sich weiterhin über die relativen Vorzüge verschiedener Arten der Zeichenfolgenformatierung %einig , aber es ist auch klar, dass die Formatierung nicht veraltet oder entfernt wird.

Darüber hinaus hat die letzte Änderung dieses Absatzes im März 2017 diesen ...

Die hier beschriebenen Formatierungsvorgänge weisen eine Vielzahl von Macken auf, die zu einer Reihe häufiger Fehler führen (z. B. wenn Tupel und Wörterbücher nicht korrekt angezeigt werden). Durch die Verwendung der neueren formatierten Zeichenfolgenliterale oder der str.formatBenutzeroberfläche können diese Fehler vermieden werden. Diese Alternativen bieten auch leistungsfähigere, flexiblere und erweiterbarere Ansätze zum Formatieren von Text.

... dazu:

Die hier beschriebenen Formatierungsvorgänge weisen eine Vielzahl von Macken auf, die zu einer Reihe häufiger Fehler führen (z. B. wenn Tupel und Wörterbücher nicht korrekt angezeigt werden). Durch die Verwendung der neueren formatierten Zeichenfolgenliterale, der str.formatBenutzeroberfläche oder der Vorlagenzeichenfolgen können diese Fehler vermieden werden. Jede dieser Alternativen bietet ihre eigenen Kompromisse und Vorteile in Bezug auf Einfachheit, Flexibilität und / oder Erweiterbarkeit.

Beachten Sie, dass der Wechsel von "hilft zu vermeiden" zu "hilft zu vermeiden" und wie die klare Empfehlung von .formatund F-Saiten durch flauschige, zweideutige Prosa darüber ersetzt wurde, wie jeder Stil "seine eigenen Kompromisse und Vorteile bietet" . Das heißt, es ist nicht nur eine formelle Ablehnung nicht mehr auf den Karten, sondern die aktuellen Dokumente erkennen offen an, dass die %Formatierung zumindest einige "Vorteile" gegenüber den anderen Ansätzen hat.

Ich würde daraus schließen, dass die Bewegung, %Formatierungen zu verwerfen oder zu entfernen, nicht nur ins Stocken geraten ist, sondern gründlich und dauerhaft besiegt wurde.

Mark Amery
quelle
2
Die flauschige Sprachänderung wurde hinzugefügt, um die Mercurial-Betreuer (unter anderem) zu beruhigen, die Mercurial nicht mit einer Codebasis zurücklassen wollten, die zu groß war, um die Verwendung von zu beseitigen %. Nachdem die Richtlinie "Keine großen Code-Mods" gestrichen wurde, verblassen auch ihre Einwände. Auf lange % Sicht wird die printf-Syntax ohnehin entfernt, wenn beide Formulare beibehalten werden und keine Vorteile mehr bestehen. Wir wissen nur noch nicht wann, und deshalb war es die Sprache wert, abgeschwächt zu werden.
Martijn Pieters
@MartijnPieters Interessant. Es hört sich so an, als hätten Sie viel Wissen über diese Entscheidung, das mir fehlt. Für das, was es wert ist, denke ich, dass eine gut referenzierte Antwort von Ihnen, die diese Punkte umreißt (entweder als neue Antwort oder als Bearbeitung Ihrer vorhandenen), Wert hätte.
Mark Amery
58

Die neue .format()Methode soll die alte %Formatierungssyntax ersetzen . Letztere wurde de-betont, (aber nicht offiziell als veraltet noch ). In der Methodendokumentation heißt es:

Diese Methode der String - Formatierung ist der neue Standard in Python 3 und soll bevorzugt werden , um die %in der Formatierung beschrieben String Formatierung Operationen in neuem Code.

(Hervorhebung von mir).

Zur Aufrechterhaltung der Abwärtskompatibilität und macht Übergang zu erleichtern, das alte Format wird an Ort und Stelle gelassen jetzt . Aus dem ursprünglichen PEP 3101-Vorschlag :

Abwärtskompatibilität

Die Abwärtskompatibilität kann aufrechterhalten werden, indem die vorhandenen Mechanismen beibehalten werden. Das neue System kollidiert nicht mit einem der Methodennamen der vorhandenen Zeichenfolgenformatierungstechniken, sodass beide Systeme nebeneinander existieren können, bis das ältere System nicht mehr unterstützt wird.

Beachten Sie, dass es an der Zeit ist, das ältere System zu verwerfen . Es ist nicht veraltet, aber das neue System muss verwendet werden, wenn Sie neuen Code schreiben .

Das neue System hat den Vorteil, dass Sie den Tupel- und Wörterbuchansatz des alten Formatierers kombinieren können %:

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

und ist durch den object.__format__()Hook erweiterbar, der zum Formatieren einzelner Werte verwendet wird.

Beachten Sie, dass das alte System %und die TemplateKlasse hatten, wobei letztere es Ihnen ermöglicht, Unterklassen zu erstellen, die ihr Verhalten hinzufügen oder ändern. Das neue System hat die FormatterKlasse , die gleiche Nische zu füllen.

Python 3 hat sich weiter von der Verwerfung entfernt und gibt stattdessen im Abschnitt " printfFormatierung von Zeichenfolgen im Stil" eine Warnung aus :

Hinweis : Die hier beschriebenen Formatierungsvorgänge weisen eine Reihe von Macken auf, die zu einer Reihe häufiger Fehler führen (z. B. wenn Tupel und Wörterbücher nicht korrekt angezeigt werden). Durch die Verwendung der neueren formatierten Zeichenfolgenliterale oder der str.format()Benutzeroberfläche können diese Fehler vermieden werden. Diese Alternativen bieten auch leistungsfähigere, flexiblere und erweiterbarere Ansätze zum Formatieren von Text.

Python 3.6 fügte auch formatierte Zeichenfolgenliterale hinzu , die die Ausdrücke in die Formatzeichenfolgen einfügen. Dies ist die schnellste Methode zum Erstellen von Zeichenfolgen mit interpolierten Werten und sollte verwendet werden, anstatt str.format()überall dort, wo Sie ein Literal verwenden können.

Martijn Pieters
quelle
4
Und mit können FormatterSie benutzerdefinierte Formate erstellen, wie sie datetimeObjekte verwenden. Da .formates sich um eine Funktion handelt, können Sie sie auch verwenden, um eine aufrufbare verzögerte Formatierung direkter zu erstellen: z. B.fmt = '{} - {}'.format; fmt(a, b)
Jon Clements
Ich sehe nicht, wie Templatees mit %oder mit dem alten System zusammenhängt . Insbesondere der PEP, den Sie verknüpfen, besagt, dass es zwar einige Überschneidungen zwischen diesem Vorschlag und gibt string.Template, es jedoch den Eindruck gibt, dass jeder einem bestimmten Bedarf dient und dass einer den anderen nicht umgeht. In Ihrer Antwort kann man verwirrt sein, dass die TemplateFormatierung, die Teil des alten Systems ist, ebenfalls veraltet ist.
Bakuriu
@ Bakuriu: Richtig, ich glaube ich habe diesen Teil verpasst; aber meiner Meinung nach kann die FormatterKlasse die gleichen Bedürfnisse erfüllen wie string.Template().
Martijn Pieters
1
[...]should be preferred to the % formatting[...]Dieser Teil wurde aus der Dokumentation entfernt. docs.python.org/3/library/stdtypes.html#str.format
AXO
Ich denke, dass diese Antwort derzeit irreführend ist; Die erste zitierte Passage wurde aus den Python 3-Dokumenten entfernt, und es scheint mir ziemlich klar zu sein, dass keine Absicht mehr besteht, dass eine Ablehnung erfolgt. Diese Antwort hat immer noch historischen Wert, aber ich würde gerne den Wortlaut ändern, um jegliche Andeutung zu vermeiden, dass eine Abwertung noch in den Karten ist, und einen Großteil der ersten Hälfte der Antwort so bearbeiten, dass sie in der Vergangenheitsform liegt. Ich werde es irgendwann selbst tun, wenn Sie nichts dagegen haben, aber ich dachte, ich würde zuerst einen Kommentar abgeben, um Ihnen die Möglichkeit zu geben, solche Änderungen selbst vorzunehmen, wenn Sie möchten.
Mark Amery
45

Der %Operator für die Formatierung von Zeichenfolgen ist nicht veraltet und wird trotz der anderen Antworten nicht entfernt.
Jedes Mal, wenn das Thema auf der Python-Entwicklungsliste angesprochen wird, gibt es starke Kontroversen darüber, was besser ist, aber keine Kontroversen darüber, ob der klassische Weg entfernt werden soll - es wird bleiben. Obwohl Python 3.1 auf PEP 3101 bezeichnet wurde, war es gekommen und gegangen, und die %Formatierung ist immer noch vorhanden.

Die Aussagen zur Beibehaltung des klassischen Stils sind klar: Es ist einfach, es ist schnell, es ist schnell für kurze Dinge zu tun. Die Verwendung der .formatMethode ist nicht immer besser lesbar - und kaum jemand - selbst unter den Kernentwicklern - kann die vollständige Syntax verwenden, die von bereitgestellt wird, .formatohne auf die Referenz achten zu müssen. Bereits 2009 hatte man Nachrichten wie diese: http: // mail. python.org/pipermail/python-dev/2009-October/092529.html - das Thema war seitdem kaum in den Listen aufgetaucht .

Update 2016

In der aktuellen Python-Entwicklungsversion (die zu Python 3.6 wird) gibt es eine dritte Methode zur String-Interpolation, die in PEP-0498 beschrieben wird . Es definiert eine neue Quote Präfix f""(neben der aktuellen u"", b""und r"").

Durch das Präfixieren eines Strings durch fwird zur Laufzeit eine Methode für das String-Objekt aufgerufen, die automatisch Variablen aus dem aktuellen Bereich in den String interpoliert:

>>> value = 80
>>> f'The value is {value}.'
'The value is 80.'
jsbueno
quelle
3
Es ist viel schöner, Typen zu erlauben, ihre eigenen zu implementieren __format__. Zum Beispiel format(Decimal('0.1'), '.20f')vs '%.20f' % Decimal('0.1'). Letzteres zwingt die Dezimalstelle zu einem Float.
Eryk Sun
2
NB. Ich habe nicht argumentiert, dass der alte Stil in jeder Hinsicht besser ist - nur dass er kürzer und manchmal besser lesbar ist (und manchmal nicht). Sicher ist der neue Weg viel flexibler.
Jsbueno
Gibt es ein Äquivalent für fin Python 3?
Daniel
Die f-stringsoben verwendeten sind neue Funktionen in der Sprache ab Python 3.6. Es ist in früheren Versionen nicht vorhanden und löst bei diesen einen Syntaxfehler aus.
Jsbueno
20

Guidos jüngste Position dazu scheint hier angegeben zu sein:

Was ist neu in Python 3.0?

PEP 3101: Ein neuer Ansatz zur Formatierung von Zeichenfolgen

Ein neues System für integrierte Formatierungsvorgänge für Zeichenfolgen ersetzt den Formatierungsoperator% string. (Der Operator% wird jedoch weiterhin unterstützt. Er wird in Python 3.1 nicht mehr unterstützt und zu einem späteren Zeitpunkt aus der Sprache entfernt.) Lesen Sie PEP 3101, um den vollständigen Überblick zu erhalten.

Und das PEP3101 selbst, dessen letzte Modifikation auf (Fr, 30. September 2011) zurückgeht, also vermutlich in letzter Zeit keine Fortschritte.

APS
quelle
18

In Bezug auf die älteren Python-Dokumente und PEP 3101 wurde festgestellt, dass der Operator% in Zukunft veraltet und aus der Sprache entfernt wird. Die folgende Anweisung war in den Python-Dokumenten für Python 3.0, 3.1 und 3.2 enthalten:

Da str.format () ziemlich neu ist, verwendet viel Python-Code immer noch den Operator%. Da dieser alte Formatierungsstil jedoch irgendwann aus der Sprache entfernt wird, sollte im Allgemeinen str.format () verwendet werden.

Wenn du zum gehst in Python 3.3- und 3.4-Dokumenten selben Abschnitt , sehen Sie, dass diese Anweisung entfernt wurde. Ich kann auch nirgendwo anders in der Dokumentation eine andere Aussage finden, die darauf hinweist, dass der Operator veraltet oder aus der Sprache entfernt wird. Es ist auch wichtig zu beachten, dass PEP3101 seit mehr als zweieinhalb Jahren nicht mehr geändert wurde (Fr, 30. September 2011).

Aktualisieren

PEP461 Das Hinzufügen von% Formatierung zu Bytes und Bytearray wird akzeptiert und sollte Teil von Python 3.5 oder 3.6 sein. Dies ist ein weiteres Zeichen dafür, dass der% -Operator lebt und tritt.

Marwan Alsabbagh
quelle