Pythonische Methode zum Erstellen einer langen mehrzeiligen Zeichenfolge

1306

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 einem +Operator zu verknüpfen (ich weiß, vielleicht ist dies nicht die effizienteste Methode, aber ich bin nicht wirklich besorgt über die Leistung in dieser Phase, sondern nur über 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 \die lange Zeichenfolge geteilt. Ich bin mir jedoch nicht sicher, ob dies der einzige / beste / pythonischste Weg ist, dies zu tun. Es sieht unangenehm 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
Pablo Mescher
quelle
207
Da Ihr Beispiel wie ein SQL-Block aussieht, der nur auf einen Injection-Angriff wartet, sollten Sie sich auch eine übergeordnete SQL-Bibliothek wie SQLAlchemy oder etwas anderes ansehen, um zu vermeiden, dass Roh-SQL wie dieses zusammengehackt wird. (Vielleicht nicht zum Thema, aber Sie haben um "Irgendwelche Vorschläge"
John Gaines Jr.
6
Dies ist "Pythonische Methode zum Erstellen eines mehrzeiligen Codes für eine lange Zeichenfolge". Informationen zum Erstellen einer Zeichenfolge mit Zeilenumbrüchen finden Sie unter textwrap.dedent .
Bob Stein
8
@cezar Ich habe diese Frage vor mehr als fünf Jahren geschrieben, aber ich erinnere mich, dass sie entstanden ist, weil ich nicht wusste, wie man die lange SQL-Abfrage richtig in mehrere Zeilen einfügt. Ich bin damit einverstanden, dass ich mit dieser langen Zeichenfolge dumme Sachen gemacht habe, aber das war nicht meine Frage, und ich war nicht klug genug, nach einem besseren Beispiel zu suchen, um es zu veranschaulichen, das einige Bedenken hinsichtlich der SQL-Injektion nicht enthielt.
Pablo Mescher
@cezar nein, dies ist kein XY-Problem, die Abfrage sollte auf jeden Fall in mehreren Zeilen formatiert werden. SQLi hat nichts mit der vorliegenden Frage zu tun. Große kühne Warnungen sind jedoch völlig gerechtfertigt :)
bugmenot123
Ich habe ein kleines Paket dafür geschrieben. Beispiel hier: stackoverflow.com/a/56940938/1842491
Shay

Antworten:

2228

Sprechen Sie über mehrzeilige Zeichenfolgen? Verwenden Sie einfach dreifache Anführungszeichen, um sie zu starten 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 swie jede andere Zeichenfolge behandeln.

HINWEIS : Wie bei jeder Zeichenfolge wird alles zwischen den Anführungszeichen am Anfang und am Ende Teil der Zeichenfolge. In diesem Beispiel wird daher ein führendes Leerzeichen angezeigt (wie in @ root45 angegeben). Diese Zeichenfolge enthält auch Leerzeichen und 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 lange Zeilen wie folgt konstruieren:

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

was wird nicht enthält keine zusätzlichen Leerzeichen oder Zeilenumbrüche (dies ist ein bewusstes Beispiel zeigt , was die Wirkung Zuschnitte des Überspringens in resultieren):

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

Es sind keine Kommas erforderlich. Platzieren Sie einfach die zu verbindenden Zeichenfolgen in Klammern und achten Sie darauf, dass alle erforderlichen Leerzeichen und Zeilenumbrüche berücksichtigt werden.

Levon
quelle
8
Ich bevorzuge es, explizit den Operator "+" für die zweite Methode zu verwenden. Kein großer Aufwand und verbessert die Lesbarkeit.
Marco Sulla
38
@LucasMalor Die benachbarten Zeichenfolgen sind eine Verkettung zur Kompilierungszeit. Wird +die Verkettung nicht zur Laufzeit mit dem Operator ausgeführt?
Joshua Taylor
13
Als Referenz sind hier die offiziellen Dokumente zu diesem Phänomen: docs.python.org/2/reference/… (Python 2) und docs.python.org/3/reference/… (Python 3)
Neverendingqs
4
Ihr Beispiel ist gut, aber ich wünschte, es hätte gezeigt, wie variable Daten sicher in die Abfrage eingebettet werden 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
2
Sie können textwrap.dedentdamit unerwünschte führende Leerzeichen entfernen. docs.python.org/3/library/textwrap.html#textwrap.dedent
Corey Goldberg
190

Wenn Sie keine mehrzeilige Zeichenfolge möchten, sondern nur eine lange einzeilige Zeichenfolge, können Sie Klammern verwenden. Stellen Sie nur sicher, dass zwischen den Zeichenfolgensegmenten keine Kommas stehen. Dann handelt es sich um 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 erstellen, sind auch mehrzeilige Zeichenfolgen in Ordnung. Wenn jedoch das zusätzliche Leerzeichen, das eine mehrzeilige Zeichenfolge enthalten würde, ein Problem darstellen würde, wäre dies ein guter Weg, um das zu erreichen, was Sie möchten.

Jesse
quelle
1
@Pablo können Sie sogar Kommentare nach dem,
Ashwini Chaudhary
@ 200OK meinst du danach '?
Kon Psych
3
Eine andere Möglichkeit, diese Zeichenfolge zu formatieren, besteht darin, sie .format(...)nach der schließenden Klammer hinzuzufügen . %Das Formatieren der Notation muss auch funktionieren, aber ich habe es nicht versucht
kon psych
3
Beachten Sie, dass jede Zeile mit einer Zeichenfolgenkonstante enden muss, damit dies ' foo '+variablenicht funktioniert, aber funktioniert ' foo '+variable+''.
Jojo
46
Dieses Beispiel ist eine offene Tür für SQL-Injection-Angriffe. Bitte, niemand verwendet dies für öffentlich zugängliche Anwendungen. Informationen
Scott Prive
138

Linien brechen durch \funktioniert für mich. 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"
amphibient
quelle
9
Ich würde entweder die dreifache Anführungszeichen oder das Umschließen von () dem Zeichen \ vorziehen
Khanh Hua
15
Ich empfehle dringend, die Leerzeichen am Anfang der folgenden Zeilen anstatt am Ende der folgenden Zeilen zu setzen. Auf diese Weise ist eine versehentlich fehlende viel offensichtlicher (und daher weniger wahrscheinlich).
Alfe
Funktioniert auch mit Variablen am ZeilenendelongStr = "account: " + account_id + \ ...
frmbelz
Ich the backslash is redundant between bracketsprint()
erhalte
50

Ich war glücklich mit diesem:

string = """This is a
very long string,
containing commas,
that I split up
for readability""".replace('\n',' ')
Eero Aaltonen
quelle
32
Nicht zustimmen. Was ist, wenn die erste Zeile ("string = ...") stark eingerückt ist? Man müsste die folgenden Zeilen auf Null einrücken, was in der Mitte eines ansonsten eingerückten Blocks hässlich aussieht.
xjcl
1
Nun, der Großteil meiner langen Saiten tritt auf Modulebene auf, wo dies gut passt. In Ihrem Fall wäre dies natürlich nicht die beste Lösung.
Eero Aaltonen
1
Ich mag diesen Ansatz, weil er das Lesen privilegiert. In Fällen, in denen wir lange Zeichenfolgen haben, gibt es keine Möglichkeit ... Abhängig von der Einrückungsstufe, in der Sie sich befinden und die immer noch auf 80 Zeichen pro Zeile beschränkt ist ... Nun ... Sie müssen nichts weiter sagen. Meiner Meinung nach sind die Python-Styleguides immer noch sehr vage. Vielen Dank!
Eduardo Lucio
Das wäre so hässlich, wenn es unter einem Modul verwendet wird, ich muss es auch.replace('\t','')
Uhr
44

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

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

Was Levon vorgeschlagen hat, ist gut, kann aber fehleranfällig sein:

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

query == "SELECT fooFROM barWHERE baz"  # probably not what you want
Darkfeline
quelle
8
+1 Erleichtert den Code-Prüfer, das rechte Ende jeder Zeile sorgfältig auf unzureichende Leerzeichen überprüfen zu müssen . Das OP hat diesen Fehler mehrmals begangen, wie von @KarolyHorvath festgestellt.
Bob Stein
2
Wenn ich mehrzeilige Zeichenfolgen überprüfe, die auf ähnliche Weise codiert sind, benötige ich zur einfachen Bestätigung ein ausreichendes Leerzeichen am linken Ende jeder Zeile.
Regenschirm
3
@ BobStein-VisiBone Code-Überprüfungen sollten sich nicht mit Syntaxfehlern oder kleinen Fehlern wie diesen befassen, sondern mit Substanz. Wenn jemand Code zur Überprüfung bereitstellt, der Syntaxfehler aufweist (und daher weder überhaupt noch in bestimmten Situationen ausgeführt wird), stimmt etwas nicht. Es ist nicht schwer, Flusen zu laufen, bevor Sie sich verpflichten. Wenn die Person nicht bemerkt hat, dass ihr Programm nicht korrekt ausgeführt wird, weil sie einen so offensichtlichen Fehler gemacht hat, sollte sie sich nicht festlegen.
Charles Addis
1
Mit @CharlesAddis einverstanden, sollten Codeüberprüfungen nach automatisierten Methoden erfolgen, z. B. nach Flusen, Syntaxhervorhebung usw. Einige Fehler, bei denen Leerzeichen fehlen, werden jedoch möglicherweise nicht auf diese Weise abgefangen. Ich schlage vor, Sie nutzen alle vernünftigen Vorteile beim Schutz vor Fehlern.
Bob Stein
33

Sie können Variablen auch verketten, 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"""

BEARBEITEN: Mit benannten Parametern und .format () einen besseren Weg gefunden:

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)
gjgjgj
quelle
26

Dieser Ansatz verwendet:

  • Nur ein Backslash, um einen anfänglichen Zeilenvorschub zu vermeiden
  • Fast keine interne Interpunktion mit einem dreifach zitierten String
  • Entfernt lokale Einrückungen mithilfe des Textwrap-inspect Moduls
  • Verwendet die für Python 3.6 formatierte String-Interpolation ('f') für die Variablen account_idund def_id.

Dieser Weg sieht für mich am pythonischsten aus.

# import textwrap  # See update to answer below
import inspect

# query = textwrap.dedent(f'''\
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}'''
)

Update : 29.01.2019 Integrieren Sie den Vorschlag von @ ShadowRanger, inspect.cleandocanstelle von zu verwendentextwrap.dedent

Christopher Bruns
quelle
5
Hinweis: inspect.cleandocist etwas schöner als textwrap.dedent, da die erste Zeile nicht leer sein muss und am Ende ein Zeilenfortsetzungszeichen steht.
ShadowRanger
2
@ShadowRanger Wow, ich habe noch nie CleanDoc verwendet. Ich habe meine Antwort aktualisiert und werde sie in Zukunft verwenden inspect.cleandoc.
Christopher Bruns
23

In Python> = 3.6 können Sie formatierte Zeichenfolgenliterale (f-Zeichenfolge) verwenden.

query= 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}'''
Vlad Bezden
quelle
4
Wie würde eine F-Zeichenfolge funktionieren, wenn ich das Ergebnis einer mehrzeiligen Zeichenfolge protokollieren möchte und die linken Tabulatoren / Leerzeichen nicht angezeigt werden?
Kuanb
7
Immer noch anfällig für SQL-Injection
Trenton
19

Zum Beispiel:

sql = ("select field1, field2, field3, field4 "
       "from table "
       "where condition1={} "
       "and condition2={}").format(1, 2)

Output: 'select field1, field2, field3, field4 from table 
         where condition1=1 and condition2=2'

Wenn der Wert der Bedingung eine Zeichenfolge sein soll, können Sie Folgendes tun:

sql = ("select field1, field2, field3, field4 "
       "from table "
       "where condition1='{0}' "
       "and condition2='{1}'").format('2016-10-12', '2017-10-12')

Output: "select field1, field2, field3, field4 from table where
         condition1='2016-10-12' and condition2='2017-10-12'"
Pangpang
quelle
13

Ich finde textwrap.dedentdas Beste für lange Saiten wie hier beschrieben :

def create_snippet():
    code_snippet = textwrap.dedent("""\
        int main(int argc, char* argv[]) {
            return 0;
        }
    """)
    do_something(code_snippet)
fredrik
quelle
1
Ich mag den schwarzen Schrägstrich, der automatisch neue Zeilen verhindert, vielen Dank!
Zyy
12

Andere haben die Klammermethode bereits erwähnt, aber ich möchte hinzufügen, dass bei Klammern Inline-Kommentare zulässig sind.

Kommentar zu jedem Fragment:

nursery_rhyme = (
    'Mary had a little lamb,'          # Comments are great!
    'its fleece was white as snow.'
    'And everywhere that Mary went,'
    'her sheep would surely go.'       # What a pesky sheep.
)

Kommentar nach Fortsetzung nicht erlaubt:

Bei Verwendung von Backslash-Zeilenfortsetzungen ( \) sind Kommentare nicht zulässig. Sie erhalten eine SyntaxError: unexpected character after line continuation characterFehlermeldung.

nursery_rhyme = 'Mary had a little lamb,' \  # These comments
    'its fleece was white as snow.'       \  # are invalid!
    'And everywhere that Mary went,'      \
    'her sheep would surely go.'
# => SyntaxError: unexpected character after line continuation character

Bessere Kommentare für Regex-Zeichenfolgen:

Basierend auf dem Beispiel von https://docs.python.org/3/library/re.html#re.VERBOSE ,

a = re.compile(
    r'\d+'  # the integral part
    r'\.'   # the decimal point
    r'\d*'  # some fractional digits
)
# Using VERBOSE flag, IDE usually can't syntax highight the string comment.
a = re.compile(r"""\d +  # the integral part
                   \.    # the decimal point
                   \d *  # some fractional digits""", re.X)
ddrscott
quelle
10

Ich persönlich finde Folgendes am besten (einfach, sicher und pythonisch), um rohe SQL-Abfragen in Python zu schreiben, insbesondere wenn Sie das sqlite3-Modul von Python verwenden :

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 = ?
        AND record_def.account_id = ?
        AND def_id = ?
'''
vars = (account_id, account_id, def_id)   # a tuple of query variables
cursor.execute(query, vars)   # using Python's sqlite3 module

Vorteile

  • Ordentlicher und einfacher Code (Pythonic!)
  • Sicher vor SQL-Injection
  • Kompatibel mit Python 2 und Python 3 (es ist schließlich Pythonic)
  • Keine Verkettung von Zeichenfolgen erforderlich
  • Sie müssen nicht sicherstellen, dass das Zeichen ganz rechts in jeder Zeile ein Leerzeichen ist

Nachteile

  • Da Variablen in der Abfrage durch den ?Platzhalter ersetzt werden, kann es etwas schwierig werden zu verfolgen, ?welche Variablen durch welche Python-Variablen ersetzt werden sollen, wenn viele davon in der Abfrage enthalten sind.
Faheel
quelle
Beachten Sie, dass ich dies nicht getestet habe, aber Sie können die Verwirrung der Fragezeichen wahrscheinlich vermeiden, indem Sie sie an den entsprechenden Stellen durch "{0} {1} {2}" ersetzen und dann die letzte Zeile in ändern cursor.execute(query.format(vars)). Das sollte sich um deinen einzigen "Betrug" kümmern (hoffe ich).
Ben
Ja, die Verwendung formatwäre nett, aber ich bin nicht sicher, ob die so formatierte Abfragezeichenfolge vor SQL-Injection sicher ist.
Faheel
Ja, das ist ein fairer Punkt und es könnte sicherlich etwas schwierig werden. Vielleicht wäre es klug, es an etwas völlig Entbehrlichem zu testen ... ohne Zweifel ein Comp. Sci. Undergrad wird früh genug vorbei wandern. ;)
Ben
2
@Ben Wenn Sie dies cursor.execute(query.format(vars))tun, profitieren Sie nicht mehr von vorbereiteten Anweisungen, sodass Sie für viele Arten von Problemen anfällig sind. Beginnen Sie mit der Tatsache, dass Sie die Parameter in der SQL-Abfrage doppelt zitieren müssen, wenn sie nicht nur Zahlen sind.
Patrick Mevzek
4

Normalerweise benutze ich so etwas:

text = '''
    This string was typed to be a demo
    on how could we write a multi-line
    text in Python.
'''

Wenn Sie störende Leerzeichen in jeder Zeile entfernen möchten, haben Sie folgende Möglichkeiten:

text = '\n'.join(line.lstrip() for line in text.splitlines())
Israel Barth Rubio
quelle
2
Schauen Sie sich Pythons textwrap.dedentFunktion an, die sich in der Standardbibliothek befindet und über die Funktionen verfügt, die Sie benötigen.
bjd2385
@ bjd2385: inspect.cleandocist etwas netter (weniger pingelig, ob Text in derselben Zeile wie die offenen Anführungszeichen angezeigt wird oder nicht, erfordert keine expliziten Zeilenfortsetzungszeichen).
ShadowRanger
3

Ihre eigentliche Code nicht funktionieren sollte, können Sie Leerzeichen am Ende von „Linien“ fehlen (zB: role.descr as roleFROM...)

Es gibt dreifache Anführungszeichen für mehrzeilige Zeichenfolgen:

string = """line
  line2
  line3"""

Es enthält Zeilenumbrüche und zusätzliche Leerzeichen, aber für SQL ist dies kein Problem.

Karoly Horvath
quelle
3

Sie können die sql-Anweisung auch in eine separate Datei einfügen action.sqlund mit in die py-Datei laden

with open('action.sql') as f:
   query = f.read()

Die SQL-Anweisungen werden also vom Python-Code getrennt. Wenn die SQL-Anweisung Parameter enthält, die aus Python ausgefüllt werden müssen, können Sie die Zeichenfolgenformatierung verwenden (z. B.% s oder {field}).

mrijken
quelle
3

"À la" Scala- Weg (aber ich denke, er ist der pythonischste Weg, den OQ verlangt):

description = """
            | The intention of this module is to provide a method to 
            | pass meta information in markdown_ header files for 
            | using it in jinja_ templates. 
            | 
            | Also, to provide a method to use markdown files as jinja 
            | templates. Maybe you prefer to see the code than 
            | to install it.""".replace('\n            | \n','\n').replace('            | ',' ')

Wenn Sie die letzte Str ohne Sprunglinien wünschen, setzen Sie einfach \nam Anfang des ersten Arguments der zweiten Ersetzung:

.replace('\n            | ',' ')`.

Hinweis: Die weiße Linie zwischen "... Vorlagen". und "Also, ..." erfordert ein Leerzeichen nach dem |.

victe
quelle
3

tl; dr: Verwenden Sie """\und """, um die Zeichenfolge wie in zu wickeln

string = """\
This is a long string
spanning multiple lines.
"""

Aus der offiziellen Python-Dokumentation :

String-Literale können mehrere Zeilen umfassen. Eine Möglichkeit ist die Verwendung von dreifachen Anführungszeichen: "" "..." "" oder "...". Das Zeilenende wird automatisch in die Zeichenfolge aufgenommen. Sie können dies jedoch verhindern, indem Sie am Zeilenende ein \ hinzufügen. Das folgende Beispiel:

print("""\
Usage: thingy [OPTIONS]
     -h                        Display this usage message
     -H hostname               Hostname to connect to
""")

erzeugt die folgende Ausgabe (beachten Sie, dass der erste Zeilenumbruch nicht enthalten ist):

Usage: thingy [OPTIONS]
     -h                        Display this usage message
     -H hostname               Hostname to connect to
Fließen
quelle
2

Hey, probieren Sie so etwas aus und hoffen Sie, dass es funktioniert. In diesem Format erhalten Sie eine durchgehende Zeile, als hätten Sie sich erfolgreich nach dieser Eigenschaft erkundigt. "

"message": f'you have successfully inquired about '
           f'{enquiring_property.title} Property owned by '
           f'{enquiring_property.client}'
Kelvin Onkundi
quelle
1

Ich verwende eine rekursive Funktion, um komplexe SQL-Abfragen zu erstellen. Diese Technik kann im Allgemeinen verwendet werden, um große Zeichenfolgen zu erstellen und gleichzeitig die Lesbarkeit des Codes zu gewährleisten.

# Utility function to recursively resolve SQL statements.
# CAUTION: Use this function carefully, Pass correct SQL parameters {},
# TODO: This should never happen but check for infinite loops
def resolveSQL(sql_seed, sqlparams):
    sql = sql_seed % (sqlparams)
    if sql == sql_seed:
        return ' '.join([x.strip() for x in sql.split()])
    else:
        return resolveSQL(sql, sqlparams)

PS: Schauen Sie sich die fantastische Python-SQLparse-Bibliothek an, um bei Bedarf hübsche SQL-Abfragen zu drucken. http://sqlparse.readthedocs.org/en/latest/api/#sqlparse.format

Sandeep
quelle
"rekursive Funktion" heißt das nicht Lambda?
m3nda
1

Eine andere Option, die meiner Meinung nach besser lesbar ist, wenn der Code (z. B. eine Variable) eingerückt ist und die Ausgabezeichenfolge ein Einzeiler sein sollte (keine Zeilenumbrüche):

def some_method():

    long_string = """
a presumptuous long string 
which looks a bit nicer 
in a text editor when
written over multiple lines
""".strip('\n').replace('\n', ' ')

    return long_string 
Eyal Levin
quelle
1

Verwenden Sie dreifache Anführungszeichen. Diese werden häufig verwendet, um zu Beginn von Programmen Dokumentzeichenfolgen zu erstellen, um deren Zweck und andere für die Erstellung relevante Informationen zu erläutern. Menschen verwenden diese auch in Funktionen, um den Zweck und die Anwendung von Funktionen zu erklären. Beispiel:

'''
Filename: practice.py
File creator: me
File purpose: explain triple quotes
'''


def example():
    """This prints a string that occupies multiple lines!!"""
    print("""
    This
    is 
    a multi-line
    string!
    """)
Joshua Hall
quelle
0

Ich mag diesen Ansatz, weil er das Lesen privilegiert. In Fällen, in denen wir lange Saiten haben, gibt es keinen Weg! Abhängig von der Einrückungsstufe, in der Sie sich befinden und die immer noch auf 80 Zeichen pro Zeile beschränkt ist ... Nun ... Sie müssen nichts weiter sagen. Meiner Meinung nach sind die Python-Styleguides immer noch sehr vage. Ich habe den @ Eero Aaltonen-Ansatz gewählt, weil er das Lesen und den gesunden Menschenverstand fördert. Ich verstehe, dass Styleguides uns helfen und unser Leben nicht durcheinander bringen sollten. Vielen Dank!

class ClassName():
    def method_name():
        if condition_0:
            if condition_1:
                if condition_2:
                    some_variable_0 =\
"""
some_js_func_call(
    undefined, 
    {
        'some_attr_0': 'value_0', 
        'some_attr_1': 'value_1', 
        'some_attr_2': '""" + some_variable_1 + """'
    }, 
    undefined, 
    undefined, 
    true
)
"""
Eduardo Lucio
quelle
0

Aus der offiziellen Python-Dokumentation :

String-Literale können mehrere Zeilen umfassen. Eine Möglichkeit ist die Verwendung von dreifachen Anführungszeichen: "" "..." "" oder "...". Das Zeilenende wird automatisch in die Zeichenfolge aufgenommen. Sie können dies jedoch verhindern, indem Sie am Zeilenende ein \ hinzufügen. Das folgende Beispiel:

print("""\
Usage: thingy [OPTIONS]
     -h                        Display this usage message
     -H hostname               Hostname to connect to
""")

erzeugt die folgende Ausgabe (beachten Sie, dass der erste Zeilenumbruch nicht enthalten ist):

Fließen
quelle
0

Um eine lange Zeichenfolge innerhalb eines Diktats zu definieren , die Zeilenumbrüche beizubehalten, aber die Leerzeichen wegzulassen , habe ich die Zeichenfolge in einer Konstanten wie der folgenden definiert:

LONG_STRING = \
"""
This is a long sting
that contains newlines.
The newlines are important.
"""

my_dict = {
   'foo': 'bar',
   'string': LONG_STRING
}
flix
quelle
0

Als allgemeine Herangehensweise an lange Zeichenfolgen in Python können Sie dreifache Anführungszeichen verwenden splitund join:

_str = ' '.join('''Lorem ipsum dolor sit amet, consectetur adipiscing 
        elit, sed do eiusmod tempor incididunt ut labore et dolore 
        magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation 
        ullamco laboris nisi ut aliquip ex ea commodo.'''.split())

Ausgabe:

'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo.'

In Bezug auf die Frage von OP zu einer SQL-Abfrage wird in der folgenden Antwort die Richtigkeit dieses Ansatzes zum Erstellen von SQL-Abfragen außer Acht gelassen, und es wird nur darauf geachtet, lange Zeichenfolgen ohne zusätzliche Importe lesbar und ästhetisch zu erstellen. Es ignoriert auch die damit verbundene Rechenlast.

Mit dreifachen Anführungszeichen erstellen wir eine lange und lesbare Zeichenfolge, die wir dann in eine Liste split()aufteilen, indem wir das Leerzeichen entfernen und es dann wieder zusammenfügen ' '.join(). Zum Schluss fügen wir die Variablen mit dem format()Befehl ein:

account_id = 123
def_id = 321

_str = '''
    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 = {} 
    AND record_def.account_id = {} 
    AND def_id = {}
    '''

query = ' '.join(_str.split()).format(account_id, account_id, def_id)

Produziert:

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 = 123 AND record_def.account_id=123 AND def_id=321

Bearbeiten: Dieser Ansatz entspricht nicht PEP8, aber ich finde ihn manchmal nützlich

Rasmus Groth
quelle
-7

Im Allgemeinen verwende ich listund joinfür mehrzeilige Kommentare / Zeichenfolgen.

lines = list()
lines.append('SELECT action.enter code here descr as "action", ')
lines.append('role.id as role_id,')
lines.append('role.descr as role')
lines.append('FROM ')
lines.append('public.role_action_def,')
lines.append('public.role,')
lines.append('public.record_def, ')
lines.append('public.action')
query = " ".join(lines)

Sie können eine beliebige Zeichenfolge verwenden, um alle diese Listenelemente wie ' \n' (Zeilenumbruch) oder ' ,' (Komma) oder ' ' (Leerzeichen) zu verbinden.

Prost..!!

paone
quelle
1
Warum würden Sie nicht wenigstens ein Array-Literal verwenden?
Alexander - Reinstate Monica
1
Arrays werden durch eine Klassenliste dargestellt.
Schauen
Ich nehme an, das funktioniert, aber Sie sollten über Leistung und Lesbarkeit nachdenken ...
Petro