Warum ist% s besser als + für die Verkettung?

88

Ich verstehe, dass wir verwenden sollten, %sum eine Zeichenfolge zu verketten, anstatt +in Python.

Ich könnte Folgendes tun:

hello = "hello"
world = "world"

print hello + " " + world
print "%s %s" % (hello, world)
print "{} {}".format(hello, world)
print ' '.join([hello, world])

Aber warum sollte ich etwas anderes als das verwenden +? Es ist schneller, Verkettung mit einem einfachen zu schreiben +. Wenn Sie sich dann die Formatierungszeichenfolge ansehen, geben Sie die Typen eg %sund %dund so an. Ich verstehe, es könnte besser sein, explizit über den Typ zu sprechen.

Aber dann habe ich gelesen, dass das Verwenden +für die Verkettung vermieden werden sollte, obwohl es einfacher zu tippen ist. Gibt es einen klaren Grund, warum Zeichenfolgen auf eine dieser anderen Arten verkettet werden sollten?

Niklas Rosencrantz
quelle
29
Wer hat dir gesagt, dass es besser ist?
Yannis
3
%sdient nicht der Verkettung, sondern ist eine Konvertierungsspezifikation für die Formatierung von Zeichenfolgen, die von C abgeleitet ist printf(3). Es gibt Fälle, in denen Sie diesen oder einen Verkettungsoperator verwenden müssen. Was Sie verwenden, sollte auf der Beurteilung der Situation beruhen, nicht auf einem Dogma. Wie einfach es ist, den Code zu schreiben, ist völlig irrelevant, da Sie dies nur einmal tun werden.
Blrfl
Ich habe die Frage nur auf Python konzentriert (obwohl ich keine Python-Person bin und möglicherweise immer noch Pannen im Code sind). Vergewissern Sie sich, dass dies die Frage ist, die Sie stellen, nehmen Sie geeignete Aktualisierungen vor und überlegen Sie, eine andere Frage zu stellen, wenn Sie an C oder Java interessiert sind.
12
Und jetzt haben wir die überlegenen F-Saiten ! print(f"{hello} {world}"), hat Lesbarkeit der Verkettung, da Variablen dort angezeigt werden, wo sie in der Zeichenfolge vorkommen, und ist schneller als str.format.
Enrico Borba

Antworten:

88
  1. Lesbarkeit. Die Formatstringsyntax ist besser lesbar, da sie den Stil von den Daten trennt. In Python %serzwingt die Syntax automatisch alle Nicht- strTypen von str; während Verkettung funktioniert nur mit str, und Sie können nicht verketten strmit int.

  2. Performance. In Python strist unveränderlich, so dass die linke und rechte Zeichenfolge für jedes Paar der Verkettung in die neue Zeichenfolge kopiert werden müssen. Wenn Sie vier Zeichenfolgen mit der Länge 10 verketten, kopieren Sie (10 + 10) + (10 + 10) + 10) + ((10 + 10) + 10) + 10) = 90 Zeichen anstelle von nur 40 Zeichen Figuren. Und mit zunehmender Anzahl und Größe der Saite wird es quadratisch schlimmer. Java optimiert diesen Fall manchmal, indem es die zu verwendende Verkettungsserie umwandelt StringBuilder, CPython jedoch nicht.

  3. In einigen Anwendungsfällen stellt die Protokollierungsbibliothek eine API bereit, die Formatzeichenfolgen verwendet, um die Zeichenfolge für Protokolleinträge träge ( logging.info("blah: %s", 4)) zu erstellen . Dies ist ideal für eine verbesserte Leistung, wenn die Protokollbibliothek feststellt, dass der aktuelle Protokolleintrag von einem Protokollfilter verworfen wird, sodass die Zeichenfolge nicht formatiert werden muss.

Lüge Ryan
quelle
31
Haben Sie eine wissenschaftliche oder empirische Quelle für # 1? Weil ich denke, dass es viel weniger lesbar ist (besonders mit mehr als zwei oder drei Argumenten)
Lovis
4
@ L.Möller: Ich bin mir nicht ganz sicher, welche Art von Quelle Sie von einer letztendlich subjektiven Erfahrung erwarten (einfache Lesbarkeit), aber wenn Sie meine Argumentation wollen: 1)% s erfordert 2 zusätzliche Zeichen pro Platzhalter vs + erfordert Mindestens 4 (oder 8, wenn Sie PEP8 befolgen, 13, wenn Sie erzwingen), 2)% s ist in einer einzelnen Zeichenfolge eingeschlossen, sodass das visuelle Parsen einfacher ist. Mit + haben Sie mehr bewegliche Teile: Zeichenfolge schließen, Operator, Variable , operator, open string, 3) syntax coloring% s hat eine Farbe für jede Funktion: string und placeholder, mit + erhalten Sie drei Farben: string, operator und variable coloring.
Lie Ryan
4
@ L.Möller: 4) Ich habe die Möglichkeit, längere Formatierungszeichenfolgen in eine Variable oder ein Wörterbuch einzufügen, sofern keine Formatierung erforderlich ist. 5) Die Formatierungszeichenfolge kann vom Benutzer in einer Konfigurationsdatei, in Befehlsargumenten oder in einer Datenbank angegeben werden Dasselbe gilt nicht für Verkettungen. Aber ja, ich würde% s auch nicht verwenden, wenn ich mehr als 4-5 Dinge zu interpolieren habe, stattdessen würde ich die Variante von% (varname) oder "{foo}". Format () in Python verwenden. Ich denke, dass die expliziten Namen die Lesbarkeit für längere Formatzeichenfolgen mit vielen interpolierten Variablen verbessern.
Lie Ryan
2
Ich weiß nicht, was "wahr" ist, deshalb frage ich, ob Sie Beweise haben :-). Stimmen Sie wirklich mit Ihrem zweiten Kommentar überein
Lovis
6
Ich finde # 2 verdächtig - haben Sie Beweise dokumentiert? Ich bin mit Java nicht besonders vertraut, aber in C # ist die Verkettung schneller als die String-Interpolation . Ich stimme # 1 voll und ganz zu und verlasse mich wirklich darauf, um zu entscheiden, wann welche verwendet werden soll, aber Sie müssen bedenken, dass die Interpolation eine Menge String-Analyse und Komplexität erfordert, während die Verkettung nichts davon erfordert.
Jimmy Hoffa
48

Bin ich der einzige, der von links nach rechts liest?

Verwenden %sist für mich wie das Hören von Deutschsprechern, bei denen ich bis zum Ende eines sehr langen Satzes warten muss, um zu hören, was das Verb ist.

Was ist auf einen Blick klarer?

"your %s is in the %s" % (object, location)

oder

"your " + object + " is in the " + location  
Mawg
quelle
17
Das ist natürlich subjektiv, da ich das erste besser lesbar finde - und es einfacher zu schreiben und zu bearbeiten ist. Die zweite Option vermischt den Text mit Code, der beide verdeckt und Rauschen hinzufügt. Zum Beispiel ist es einfach, die Leerzeichen in der Sekunde falsch zu machen.
JacquesB
5
@JacquesB Ich glaube, Ihr Gehirn ist mit diesem Format so vertraut, dass Sie sofort zu den Klammern springen und die Wörter sofort ersetzen. Technisch ist es nicht von links nach rechts zu lesen, aber das ist vollkommen in Ordnung. Ich finde, dass ich das auch tue, also ist 1 leichter zu lesen, weil ich weiß, dass ich mich mit dummen Abstandsfragen vor und nach den Anführungszeichen in der zweiten beschäftigen muss, und das ist sehr langsam.
Nelson
3
Nach nJahrzehnten funktioniert mein Verstand auch so ;-) Aber ich stehe immer noch zu meiner Antwort, die zweite ist klarer und leichter zu lesen, daher zu pflegen. Und das wird umso deutlicher, je mehr Parameter Sie haben. Wenn es sich letztendlich um eine One-Man-Show handelt, sollten Sie sich an das halten, mit dem Sie vertraut und vertraut sind. Wenn es sich um eine Teamleistung handelt, setzen Sie Konsistenz- und Codeüberprüfungen durch. Die Leute können sich daran gewöhnen.
Mawg
4
Das erste ist für mich viel lesbarer, weil es in der Mitte des Satzes weniger "cruft" hat. Es ist für mein Auge einfacher, bis zum Ende zu schauen, als für mein Gehirn, die zusätzlichen Anführungszeichen, Leerzeichen und Pluspunkte herauszusuchen. Natürlich ziehe ich jetzt viel Strings Python 3.6 - Format: f"your {object} is in the {location}".
Dustin Wyatt
8
Ich finde es auch noch schwieriger zu lesen und zu schreiben, wenn die Variable selbst in Anführungszeichen gesetzt werden muss. "your '" + object + "' is in the '" + location + "'"... Ich bin mir nicht mal sicher, ob ich das gerade richtig verstanden habe ...
Dustin Wyatt
12

Ein Beispiel zur Verdeutlichung der Lesbarkeit:

print 'id: ' + id + '; function: ' + function + '; method: ' + method + '; class: ' + class + ' -- total == ' + total

print 'id: %s; function: %s; method: %s; class: %s --total == %s' % \
   (id, function, method, class, total)

(Beachten Sie, dass das zweite Beispiel nicht nur besser lesbar ist, sondern auch einfacher zu bearbeiten ist. Sie können die Vorlage in einer Zeile und die Liste der Variablen in einer anderen ändern.)

Ein separates Problem ist, dass% s-Code auch in die Zeichenfolge konvertiert wird. Andernfalls müssen Sie den Aufruf str () verwenden, der auch weniger lesbar ist als ein% s-Code.

Regnerisch
quelle
1
Ich bin mit Ihrer ersten Aussage nicht einverstanden, aber wir können uns darauf einigen, dass wir uns unterscheiden. Ich wollte gerade eine Antwort in Anlehnung an Ihre zweite abgeben, also stimmen Sie zu
Mawg,
6

Die Verwendung +sollte im Allgemeinen nicht vermieden werden. In vielen Fällen ist der richtige Ansatz. Die Verwendung von %soder .join()ist nur in bestimmten Fällen vorzuziehen, und es ist normalerweise ziemlich offensichtlich, wann sie die bessere Lösung sind.

In Ihrem Beispiel verknüpfen Sie drei Zeichenfolgen miteinander, und die Verwendung des Beispiels +ist eindeutig die einfachste und am besten lesbare und daher die empfohlene.

%soder .format()sind nützlich, wenn Sie Zeichenfolgen oder Werte in der Mitte einer größeren Zeichenfolge interpolieren möchten . Beispiel:

print "Hello %s, welcome to the computer!" % name

In diesem Fall ist die Verwendung %sbesser lesbar, da Sie vermeiden, die erste Zeichenfolge in mehrere Segmente zu teilen. Besonders wenn Sie mehrere Werte interpolieren.

.join() Dies ist sinnvoll, wenn Sie eine Folge von Zeichenfolgen variabler Größe haben und / oder mehrere Zeichenfolgen mit demselben Trennzeichen verketten möchten.

JacquesB
quelle
2

Da sich die Wortreihenfolge in verschiedenen Sprachen ändern kann, ist das Formular mit %sunbedingt erforderlich, wenn Sie die Übersetzung von Zeichenfolgen in Ihrer Software ordnungsgemäß unterstützen möchten.

martjno
quelle