Wie teile ich die Definition einer langen Zeichenfolge auf mehrere Zeilen auf?

Lesezeit: 11 Minuten

Benutzer-Avatar
Pablo Mescher

Ich habe eine sehr lange Anfrage. Ich möchte es in Python in mehrere Zeilen aufteilen. Eine Möglichkeit, dies in JavaScript zu tun, besteht darin, mehrere Sätze zu verwenden und sie mit a zu verbinden + Operator (Ich weiß, vielleicht ist es nicht der effizienteste Weg, aber ich mache mir in dieser Phase keine Sorgen um die Leistung, nur um die Lesbarkeit des Codes). Beispiel:

var long_string = 'some text not important. just garbage to' +
                      'illustrate my example';

Ich habe versucht, etwas Ähnliches in Python zu tun, aber es hat nicht funktioniert, also habe ich es verwendet \ um die lange Schnur zu teilen. Ich bin mir jedoch nicht sicher, ob dies der einzige / beste / pythonischste Weg ist, dies zu tun. Es sieht umständlich aus. Aktueller Code:

query = 'SELECT action.descr as "action", '\
    'role.id as role_id,'\
    'role.descr as role'\
    'FROM '\
    'public.role_action_def,'\
    'public.role,'\
    'public.record_def, '\
    'public.action'\
    'WHERE role.id = role_action_def.role_id AND'\
    'record_def.id = role_action_def.def_id AND'\
    'action.id = role_action_def.action_id AND'\
    'role_action_def.account_id = ' + account_id + ' AND'\
    'record_def.account_id=' + account_id + ' AND'\
    'def_id=' + def_id

  • Da Ihr Beispiel wie ein SQL-Block aussieht, der nur auf einen Injektionsangriff wartet, ist ein weiterer Vorschlag, in eine SQL-Bibliothek auf höherer Ebene wie SQLAlchemy oder etwas zu schauen, um das Zusammenhacken von rohem SQL wie diesem zu vermeiden. (Vielleicht Off-Topic, aber Sie haben nach “Irgendwelche Vorschläge” gefragt. 😉

    – John Gaines jr.

    18. Mai 2012 um 22:26 Uhr

  • Dies ist “Pythonic Art zu erstellen mehrzeiliger Code für eine lange Zeichenfolge” Um eine Zeichenfolge zu erstellen Zeilenumbrüche enthalten siehe textwrap.dent.

    – Bob Stein

    29. Januar 2015 um 17:16 Uhr


  • @cezar Ich habe diese Frage vor mehr als fünf Jahren geschrieben, aber ich erinnere mich, dass sie daraus entstand, dass ich nicht wusste, wie man die lange SQL-Abfrage richtig in mehrere Zeilen einfügt. Ich stimme zu, dass ich mit dieser langen Zeichenfolge dumme Dinge getan habe, aber das war nicht meine Frage, und ich war nicht schlau genug, um nach einem besseren Beispiel zu suchen, um dies zu veranschaulichen, das einige Bedenken hinsichtlich der SQL-Injektion nicht enthielt.

    – Pablo Mescher

    23. Januar 2018 um 19:42 Uhr

  • @cezar nein, das ist kein XY-Problem, die Abfrage wäre auf jeden Fall am besten mehrzeilig formatiert. SQLi hat nichts mit der vorliegenden Frage zu tun. Große fette Warnungen sind jedoch völlig gerechtfertigt 🙂

    – bugmenot123

    4. April 2019 um 13:23 Uhr


  • Dazu habe ich ein kleines Paket geschrieben. Beispiel hier: stackoverflow.com/a/56940938/1842491

    – Shay

    24. Januar 2020 um 14:49 Uhr

Benutzer-Avatar
Levon

Meinst du mehrzeilige Strings? Einfach, verwenden Sie dreifache Anführungszeichen, um sie zu beginnen und zu beenden.

s = """ this is a very
        long string if I had the
        energy to type more and more ..."""

Sie können auch einfache Anführungszeichen verwenden (3 davon natürlich am Anfang und am Ende) und die resultierende Zeichenfolge behandeln s genau wie jede andere Saite.

HINWEIS: Genau wie bei jedem String wird alles zwischen den Anführungszeichen am Anfang und am Ende Teil des Strings, also hat dieses Beispiel ein führendes Leerzeichen (wie von @root45 gezeigt). Diese Zeichenfolge enthält außerdem sowohl Leerzeichen als auch Zeilenumbrüche.

Dh:

' this is a very\n        long string if I had the\n        energy to type more and more ...'

Schließlich kann man in Python auch so lange Zeilen konstruieren:

 s = ("this is a very"
      "long string too"
      "for sure ..."
     )

welches wird nicht Fügen Sie alle zusätzlichen Leerzeichen oder Zeilenumbrüche ein (dies ist ein absichtliches Beispiel, das zeigt, was der Effekt des Überspringens von Leerzeichen zur Folge hat):

'this is a verylong string toofor sure ...'

Es sind keine Kommas erforderlich, setzen Sie einfach die zu verbindenden Zeichenfolgen in ein Paar Klammern und achten Sie darauf, alle erforderlichen Leerzeichen und Zeilenumbrüche zu berücksichtigen.

  • Ich ziehe es vor, explizit den “+”-Operator für die zweite Methode zu verwenden. Kein großer Aufwand und verbessert die Lesbarkeit.

    – Marco Sulla

    14. August 2014 um 10:49 Uhr


  • @LucasMalor Die angrenzenden Zeichenfolgen sind eine Verkettung zur Kompilierzeit. Benutzt die nicht + Operator die Verkettung zur Laufzeit durchführen?

    – Josua Taylor

    25. November 2014 um 15:26 Uhr

  • Als Referenz finden Sie hier die offiziellen Dokumente zu diesem Phänomen: docs.python.org/2/reference/… (Python 2) und docs.python.org/3/reference/… (Python 3)

    – nie endendeqs

    15. August 2016 um 13:16 Uhr

  • Ihr Beispiel ist gut, aber ich wünschte, es hätte gezeigt, wie Sie variable Daten sicher in die Abfrage einbetten können. Sowohl der OP- als auch der @jessee-Beispielcode zeigen, wie man es NICHT richtig macht (sie sind Einladungen zu SQL-Angriffen). Siehe auch: dev.mysql.com/doc/connector-python/en/…

    – Scott Prive

    8. Oktober 2016 um 17:29 Uhr


  • Sie können verwenden textwrap.dedent um unerwünschte führende Leerzeichen zu entfernen. docs.python.org/3/library/textwrap.html#textwrap.deent

    – Corey Goldberg

    27. November 2017 um 15:43 Uhr

Benutzer-Avatar
Jesse

Wenn Sie keine mehrzeilige Zeichenfolge, sondern nur eine lange einzeilige Zeichenfolge haben möchten, können Sie Klammern verwenden. Stellen Sie nur sicher, dass Sie keine Kommas zwischen den Zeichenfolgesegmenten einfügen (dann wird es ein Tupel).

query = ('SELECT   action.descr as "action", '
         'role.id as role_id,'
         'role.descr as role'
         ' FROM '
         'public.role_action_def,'
         'public.role,'
         'public.record_def, '
         'public.action'
         ' WHERE role.id = role_action_def.role_id AND'
         ' record_def.id = role_action_def.def_id AND'
         ' action.id = role_action_def.action_id AND'
         ' role_action_def.account_id = '+account_id+' AND'
         ' record_def.account_id='+account_id+' AND'
         ' def_id='+def_id)

In einer SQL-Anweisung wie der, die Sie konstruieren, wären auch mehrzeilige Zeichenfolgen in Ordnung. Aber wenn der zusätzliche Leerraum, den eine mehrzeilige Zeichenfolge enthalten würde, ein Problem darstellen würde, wäre dies eine gute Möglichkeit, das zu erreichen, was Sie wollen.

Wie in den Kommentaren angemerkt, Das Verketten von SQL-Abfragen auf diese Weise ist ein Sicherheitsrisiko durch SQL-Injektion, das nur darauf wartet, passiert zu werden, verwenden Sie also die Funktion für parametrisierte Abfragen Ihrer Datenbank, um dies zu verhindern. Ich lasse die Antwort jedoch unverändert, da sie die gestellte Frage direkt beantwortet.

  • @Pablo Sie können danach sogar Kommentare hinzufügen ,

    – Ashwini Chaudhary

    18. Mai 2012 um 22:45 Uhr

  • @200OK du meinst danach '?

    – kon psych

    15. Juni 2014 um 6:14 Uhr

  • Eine andere Möglichkeit, diese Zeichenfolge zu formatieren, wäre das Hinzufügen .format(...) nach der schließenden Klammer. % Die Formatierung muss auch funktionieren, aber ich habe es nicht versucht

    – kon psych

    15. Juni 2014 um 6:16 Uhr

  • Beachten Sie, dass jede Zeile mit einer String-Konstante enden muss, also ' foo '+variable wird nicht funktionieren, aber ' foo '+variable+'' Wille.

    – Jojo

    8. Juli 2015 um 6:57 Uhr


  • Dieses Beispiel ist eine offene Tür für SQL-Injection-Angriffe. Bitte verwenden Sie dies nicht für öffentlich zugängliche Anwendungen. Siehe die MySQL-Dokumentation für die Verwendung von „Platzhaltern“: dev.mysql.com/doc/connector-python/en/…

    – Scott Prive

    8. Oktober 2016 um 17:30 Uhr

Linien brechen durch \ funktioniert bei mir. Hier ist ein Beispiel:

longStr = "This is a very long string " \
        "that I wrote to help somebody " \
        "who had a question about " \
        "writing long strings in Python"

  • Ich würde entweder die Notation mit dreifachen Anführungszeichen oder das Umschließen von () gegenüber dem \-Zeichen bevorzugen

    – Khan Hua

    3. Januar 2016 um 9:32 Uhr

  • Ich empfehle dringend, die Leerzeichen am Anfang der folgenden Zeilen zu setzen, anstatt am Ende der folgenden Zeilen. Auf diese Weise ist ein versehentliches Fehlen viel offensichtlicher (und daher weniger wahrscheinlich).

    – Alfe

    20. Dezember 2017 um 14:39 Uhr

  • Funktioniert auch mit Variablen am Zeilenende longStr = "account: " + account_id + \ ...

    – frmbelz

    5. Dezember 2019 um 22:56 Uhr


  • Ich erhalte folgenden Fehler: the backslash is redundant between brackets als ich hinein schrieb print()

    – Alper

    25. Mai 2020 um 19:35 Uhr

  • @Alfe Sie müssen sich keine Sorgen mehr über fehlende \’s machen. VScode wird einen Herzinfarkt bekommen, wenn ich einen verpasse

    – Arthur Tarasov

    23. Juli 2020 um 2:18 Uhr

Benutzer-Avatar
Eero Aaltonen

Ich fand mich glücklich mit diesem:

string = """This is a
very long string,
containing commas,
that I split up
for readability""".replace('\n',' ')

Benutzer-Avatar
Dunkelkatze

Ich finde, dass Sie beim Erstellen langer Zeichenfolgen normalerweise so etwas wie das Erstellen einer SQL-Abfrage tun. In diesem Fall ist dies am besten:

query = ' '.join((  # Note double parentheses. join() takes an iterable
    "SELECT foo",
    "FROM bar",
    "WHERE baz",
))

Was Levon vorgeschlagen hat, ist gut, aber es könnte anfällig für Fehler sein:

query = (
    "SELECT foo"
    "FROM bar"
    "WHERE baz"
)

query == "SELECT fooFROM barWHERE baz"  # Probably not what you want

  • +1 Entlastet den Code-Reviewer davon, das rechte Ende jeder Zeile eifrig zu überprüfen unzureichender Leerraum. Das OP hat diesen Fehler mehrmals begangen, wie von @KarolyHorvath bemerkt.

    – Bob Stein

    30. Januar 2015 um 15:53 ​​Uhr

  • Beim Überprüfen von mehrzeiligen Zeichenfolgen, die auf ähnliche Weise codiert sind, benötige ich ausreichend Leerzeichen auf der links Ende jeder Zeile zur einfachen Bestätigung.

    – Regenschirm

    21. September 2016 um 14:13 Uhr

  • @BobStein-VisiBone Code-Reviews sollten sich nicht um Syntaxfehler oder kleine Fehler wie diese drehen, sondern um die Substanz. Wenn jemand Code zur Überprüfung vorlegt, der Syntaxfehler aufweist (und daher entweder gar nicht oder in bestimmten Situationen nicht ausgeführt wird), dann stimmt etwas ernsthaft nicht. Es ist nicht schwer, Lint auszuführen, bevor Sie sich festlegen. Wenn die Person nicht bemerkt hat, dass ihr Programm nicht richtig läuft, weil sie einen so offensichtlichen Fehler gemacht hat, sollte sie sich nicht verpflichten.

    – Charles D Pantoga

    17. Oktober 2016 um 18:24 Uhr


  • Einverstanden @CharlesAddis, Codeüberprüfungen sollten nach automatisierten Methoden erfolgen, z. B. Flusen, Syntaxhervorhebung usw. Einige Fehler mit fehlenden Leerzeichen werden jedoch möglicherweise nicht auf diese Weise abgefangen. Nutzen Sie alle vernünftigen Vorteile beim Schutz vor Fehlern, schlage ich vor.

    – Bob Stein

    17. Oktober 2016 um 18:32 Uhr

  • Ein zusätzlicher Vorteil ist, dass Sie Zeilen schnell auskommentieren können.

    – Ideogramm

    23. Februar um 11:52 Uhr

Benutzer-Avatar
Peter Mortensen

Dieser Ansatz verwendet:

  • fast keine interne Interpunktion durch die Verwendung einer Zeichenfolge in dreifachen Anführungszeichen
  • entfernt lokale Einkerbungen mit dem inspect Modul
  • verwendet Python 3.6-formatierte Zeichenfolgeninterpolation (‘f’) für die account_id und def_id Variablen.

Dieser Weg sieht für mich am pythonischsten aus.

import inspect

query = inspect.cleandoc(f'''
    SELECT action.descr as "action",
    role.id as role_id,
    role.descr as role
    FROM
    public.role_action_def,
    public.role,
    public.record_def,
    public.action
    WHERE role.id = role_action_def.role_id AND
    record_def.id = role_action_def.def_id AND
    action.id = role_action_def.action_id AND
    role_action_def.account_id = {account_id} AND
    record_def.account_id={account_id} AND
    def_id={def_id}'''
)

  • +1 Entlastet den Code-Reviewer davon, das rechte Ende jeder Zeile eifrig zu überprüfen unzureichender Leerraum. Das OP hat diesen Fehler mehrmals begangen, wie von @KarolyHorvath bemerkt.

    – Bob Stein

    30. Januar 2015 um 15:53 ​​Uhr

  • Beim Überprüfen von mehrzeiligen Zeichenfolgen, die auf ähnliche Weise codiert sind, benötige ich ausreichend Leerzeichen auf der links Ende jeder Zeile zur einfachen Bestätigung.

    – Regenschirm

    21. September 2016 um 14:13 Uhr

  • @BobStein-VisiBone Code-Reviews sollten sich nicht um Syntaxfehler oder kleine Fehler wie diese drehen, sondern um die Substanz. Wenn jemand Code zur Überprüfung einreicht, der Syntaxfehler aufweist (und daher entweder gar nicht oder in bestimmten Situationen nicht ausgeführt wird), dann stimmt etwas ernsthaft nicht. Es ist nicht schwer, Lint auszuführen, bevor Sie sich festlegen. Wenn die Person nicht bemerkt hat, dass ihr Programm nicht richtig läuft, weil sie einen so offensichtlichen Fehler gemacht hat, sollte sie sich nicht verpflichten.

    – Charles D Pantoga

    17. Oktober 2016 um 18:24 Uhr


  • Einverstanden @CharlesAddis, Codeüberprüfungen sollten nach automatisierten Methoden erfolgen, z. B. Flusen, Syntaxhervorhebung usw. Einige Fehler mit fehlenden Leerzeichen werden jedoch möglicherweise nicht auf diese Weise abgefangen. Nutzen Sie alle vernünftigen Vorteile beim Schutz vor Fehlern, schlage ich vor.

    – Bob Stein

    17. Oktober 2016 um 18:32 Uhr

  • Ein zusätzlicher Vorteil ist, dass Sie Zeilen schnell auskommentieren können.

    – Ideogramm

    23. Februar um 11:52 Uhr

Benutzer-Avatar
Peter Mortensen

Sie können auch Variablen einschließen, wenn Sie die Notation “”” verwenden:

foo = '1234'

long_string = """fosdl a sdlfklaskdf as
as df ajsdfj asdfa sld
a sdf alsdfl alsdfl """ +  foo + """ aks
asdkfkasdk fak"""

Ein besserer Weg ist mit benannten Parametern und .format():

body = """
<html>
<head>
</head>
<body>
    <p>Lorem ipsum.</p>
    <dl>
        <dt>Asdf:</dt>     <dd><a href="{link}">{name}</a></dd>
    </dl>
    </body>
</html>
""".format(
    link='http://www.asdf.com',
    name="Asdf",
)

print(body)

  • Die Verwendung von f-Saiten scheint hier natürlicher und einfacher zu sein.

    –Timo

    3. März 2021 um 19:30 Uhr

1159420cookie-checkWie teile ich die Definition einer langen Zeichenfolge auf mehrere Zeilen auf?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy