
Python bietet drei Möglichkeiten zum Formatieren von Zeichenfolgen. Eine davon ist besser als die anderen. Aber lasst uns nicht weiterkommen - über welche Art von Formatierung sprechen wir? Jedes Mal, wenn wir einen Benutzer mit seinem Namen begrüßen möchten, müssen wir eine Zeichenfolge mit einem Namen in die Vorlagenzeichenfolge einfügen. Die nützlichsten Protokolleinträge enthalten auch Variablenwerte. Und hier ist ein Beispiel:
integer = 42 string = 'FORTY_TWO' print('string number %s, or simply %d' % (string, integer)) print('string number {}, or simply {}'.format(string, integer)) print(f'string number {string}, or simply {integer}')
Die erste Methode, die mit dem Operator% formatiert wurde, kam in Python von C - sie ahmt die Funktion printf nach. Diese Methode war die erste in Python und ist nach wie vor die einzige (im Artikel beschrieben) in Python Version 2.5 und darunter.
Der zweite Weg ist die str.format-Methode, die zur integrierten String-Klasse gehört. Es wurde mit Python 3.0 geliefert und auf Version 2.6 portiert. Diese Methode wurde mit einer umfassenderen Syntax
empfohlen .
Die dritte Methode, f-string, wurde in Python Version 3.6 veröffentlicht. Wie in
PEP-0498 erläutert , wurde die Schaffung einer neuen Methode zum Formatieren von Zeichenfolgen durch die Mängel bestehender Methoden motiviert, die die Autoren als fehleranfällig, nicht flexibel genug und nicht elegant charakterisieren:
Dieses PEP basiert auf dem Wunsch, Zeichenfolgen in Python einfacher zu formatieren. Die vorhandenen Formatierungsmethoden sind entweder fehleranfällig, unflexibel oder umständlich.
Wir haben also drei Möglichkeiten, um ein Problem zu lösen. Aber vielleicht ist dies eine Frage des persönlichen Geschmacks und der Vorlieben? Vielleicht, aber der Stil Ihres Codes (insbesondere der Code in einem Projekt mit einer großen Anzahl von Teilnehmern) wird definitiv von der Einheitlichkeit profitieren. Im besten Fall sollten Sie eine Methode zum Formatieren von Zeichenfolgen verwenden, damit das Lesen des Codes einfacher wird. Aber welche Methode soll man wählen? Und gibt es einen Unterschied in der Codeleistung?
Versuchen wir, die Frage nach der Leistung experimentell zu beantworten:
import timeit setup = """ integer = 42 string = 'FORTY_TWO' """.strip() percent_stmt ="'Number %s or simply %d' % (string, integer)" call_stmt = "'Number {} or simply {}'.format(string, integer)" fstr_stmt = """f'Number {string} or simply {integer}'""" def time(stmt): return f"{timeit.timeit(stmt, setup, number=int(1e7)):.3f}" print(f"Timing percent formating: | {time(percent_stmt)}") print(f"Timing call formating: | {time(call_stmt)}") print(f"Timing f-string formating: | {time(fstr_stmt)}")
Ergebnisse auf MacBook mit Python 3.7:
Timing percent formating: | 2.025 Timing call formating: | 2.943 Timing f-string formating: | 1.348
Der Unterschied ist signifikant. Führen Sie nun die Regex-Suche für ".format" aus und schreiben Sie Hunderte von Ausdrücken neu? Grundsätzlich ist die Aufgabe einfach, aber zeitaufwändig. Plus die Chance, einen Fehler zu machen und einen Fehler in den zuvor funktionierenden Code zu setzen! Es scheint Raum für Automatisierung zu geben. In der Tat gibt es Bibliotheken, die die meisten Ausdrücke in F-Strings konvertieren können:
flynt ,
pyupgrade .
Flynt ist einfach zu bedienen. Führen Sie beispielsweise die Konvertierung für den Quellcode des Kolbens aus:
38f9d3a65222:~ ikkamens$ git clone https://github.com/pallets/flask.git Cloning into 'flask'... ... Resolving deltas: 100% (12203/12203), done. 38f9d3a65222:~ ikkamens$ flynt flask Flynt run has finished. Stats: Execution time: 0.623s Files modified: 18 Expressions transformed: 43 Character count reduction: 241 (0.04%) _-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_. Please run your tests before commiting. Report bugs as github issues at: https://github.com/ikamensh/flynt Thank you for using flynt! Fstringify more projects and recommend it to your colleagues! _-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_. 38f9d3a65222:~ ikkamens$
Es ist auch erwähnenswert, dass Ausdrücke, die mehrere Zeilen belegen, konvertiert und Statistiken über die vorgenommenen Änderungen gesammelt werden können. Das Flag --line_length XX definiert die Zeilenlängenbegrenzung nach der Konvertierung. Mit Flynt können Sie pyupgrade mit dem Flag --upgrade aufrufen.
Pyupgrade bietet mehr Funktionen und kann Ihren Code von vielen Python 2-Artefakten bereinigen - z. B. vom Erben von Objekten, Angeben von Klassennamen in Super und
vielem mehr . Pyupgrade wurde für die Verwendung mit
Pre-Commit entwickelt , einem Dienstprogramm zum automatischen Ändern von Code vor dem Festschreiben.
Es ist besser, die Quelle in eine Gita oder eine andere Versionskontrolle zu konvertieren. Es lohnt sich, Tests durchzuführen und die Änderungen selbst zu betrachten (unter Verwendung von Git Diff- oder PyCharm-Umgebungen). Solange wir unter denen leben, die sich darum kümmern, dass der Code ein paar Zeichen kürzer geworden ist, spart eine proaktive Konvertierung auch Zeit. Schließlich wird früher oder später jemand anfangen, mit seinen Händen zu tun, was zu einem Dienstprogramm gemacht werden kann. F-Strings funktionieren nur unter Python 3.6+, aber bald wird dies kein Problem mehr sein, da
andere Versionen veraltet sein werden .
Es ist erwähnenswert, dass die klassische .format-Methode nicht vollständig funktioniert. Wenn Sie dieselbe Vorlage verwenden, um Nachrichten mit unterschiedlichen Variablen an verschiedenen Stellen im Code zu erstellen, sollten Sie diese Vorlage in einer Variablen speichern und verwenden. Das Prinzip „Wiederholen Sie sich nicht“ ist viel wichtiger als das Gewinnen von Nanosekunden nach dem Formatieren einer Zeichenfolge.
Schlussfolgerungen:
Wir haben uns die drei in Python 3.6+ verfügbaren Formatierungsmethoden für Zeichenfolgen und ihren kurzen Verlauf angesehen und ihre Leistung verglichen. Wir haben auch die Open-Source-Tools zum automatischen Konvertieren von Code in eine neue Methode zum Formatieren von Zeichenfolgen und ihre zusätzlichen Funktionen untersucht. Vergessen Sie nicht die einfachen Dinge in Ihrem Code und viel Glück!