Forma pitónica de crear una cadena larga de varias líneas

1307

Tengo una consulta muy larga. Me gustaría dividirlo en varias líneas en Python. Una forma de hacerlo en JavaScript sería usar varias oraciones y unirlas con un +operador (lo sé, tal vez no sea la forma más eficiente de hacerlo, pero no estoy realmente preocupado por el rendimiento en esta etapa, solo la legibilidad del código) . Ejemplo:

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

Intenté hacer algo similar en Python, pero no funcionó, así que solía \dividir la cadena larga. Sin embargo, no estoy seguro de si esta es la única / mejor / forma más pitónica de hacerlo. Se ve incómodo. Código actual:

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
fuente
208
Dado que su ejemplo parece un bloque SQL esperando un ataque de inyección, otra sugerencia es buscar en una biblioteca SQL de nivel superior como SQLAlchemy o algo para evitar piratear SQL sin formato como este. (Quizás fuera de tema, pero solicitó "Cualquier sugerencia";)
John Gaines Jr.
66
Esta es la "forma pitónica de crear código de varias líneas para una cadena larga". Para crear una cadena que contenga nuevas líneas, consulte textwrap.dedent .
Bob Stein el
8
@cezar Escribí esta pregunta hace más de cinco años, pero recuerdo que surgió por no saber cómo colocar correctamente la consulta sql larga en varias líneas. Estoy de acuerdo en que estaba haciendo cosas estúpidas con esa larga cadena, pero esa no era mi pregunta y no era lo suficientemente inteligente como para buscar un mejor ejemplo para ilustrarlo que no incluyera algunas preocupaciones de inyección sql.
Pablo Mescher el
@cezar no, este no es un problema XY, la consulta se formateará mejor en varias líneas en cualquier caso. SQLi no está relacionado con la pregunta en cuestión. Sin embargo, las grandes advertencias en negrita están totalmente justificadas :)
bugmenot123
Escribí un pequeño paquete para esto. Ejemplo aquí: stackoverflow.com/a/56940938/1842491
Shay

Respuestas:

2229

¿Estás hablando de cadenas de varias líneas? Fácil, use comillas triples para comenzar y finalizarlas.

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

También puede usar comillas simples (3 de ellas, por supuesto, al principio y al final) y tratar la cadena resultante scomo cualquier otra cadena.

NOTA : Al igual que con cualquier cadena, cualquier cosa entre las comillas iniciales y finales se convierte en parte de la cadena, por lo que este ejemplo tiene un espacio en blanco inicial (como lo señala @ root45). Esta cadena también contendrá espacios en blanco y líneas nuevas.

Es decir,:

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

Finalmente, uno también puede construir líneas largas en Python como esta:

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

que no incluirá espacios en blanco adicionales o nuevas líneas (este es un ejemplo deliberado que muestra el resultado de omitir espacios en blanco):

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

No se requieren comas, simplemente coloque las cadenas que se unirán en un par de paréntesis y asegúrese de tener en cuenta los espacios en blanco y las nuevas líneas necesarias.

Levon
fuente
8
Prefiero usar explícitamente el operador "+" para el segundo método. No es una molestia y mejora la legibilidad.
Marco Sulla
38
@LucasMalor Las cadenas adyacentes son una concatenación en tiempo de compilación. ¿El uso del +operador no hace que la concatenación suceda en tiempo de ejecución?
Joshua Taylor
13
Como referencia, aquí están los documentos oficiales de este fenómeno: docs.python.org/2/reference/… (python 2) y docs.python.org/3/reference/… (python 3)
neverendingqs
44
Su ejemplo es bueno, pero desearía que hubiera incluido demostrar cómo incrustar de manera segura datos variables en la consulta. Tanto el código de ejemplo OP como @jessee muestran cómo NO hacerlo correctamente (son invitaciones a ataques SQL). Ver también: dev.mysql.com/doc/connector-python/en/…
Scott Prive
2
puede usar textwrap.dedentpara eliminar espacios en blanco iniciales no deseados. docs.python.org/3/library/textwrap.html#textwrap.dedent
Corey Goldberg
190

Si no desea una cadena multilínea pero solo tiene una cadena larga de una sola línea, puede usar paréntesis, solo asegúrese de no incluir comas entre los segmentos de la cadena, entonces será una tupla.

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)

En una declaración SQL como la que está construyendo, las cadenas multilínea también estarían bien. Pero si el espacio en blanco adicional que contendría una cadena multilínea sería un problema, entonces esta sería una buena manera de lograr lo que desea.

Jesse
fuente
1
@Pablo incluso se puede añadir comentarios después de la,
Ashwini Chaudhary
@ 200OK quieres decir después '?
kon psych
3
Otra forma de formatear esta cadena sería agregar .format(...)después del paréntesis de cierre. %la notación de formateo también debe funcionar, pero no lo he intentado
kon psych
3
Tenga en cuenta que cada línea debe terminar con una cadena constante, por ' foo '+variablelo que no funcionará, pero lo ' foo '+variable+''hará.
yoyo
46
Este ejemplo es una puerta abierta a los ataques de inyección SQL. Por favor, nadie use esto en ninguna aplicación pública. Consulte los documentos de MySQL para saber cómo usar 'marcadores de posición': dev.mysql.com/doc/connector-python/en/…
Scott Prive
138

Romper líneas por \obras para mí. Aquí hay un ejemplo:

longStr = "This is a very long string " \
        "that I wrote to help somebody " \
        "who had a question about " \
        "writing long strings in Python"
anfibio
fuente
99
Preferiría la notación de comillas triples o envolver dentro () al carácter \
Khanh Hua
15
Recomiendo encarecidamente colocar los espacios al comienzo de las siguientes líneas en lugar de al final de las líneas seguidas. De esta manera, una falta accidental es mucho más obvia (y por lo tanto es menos probable que suceda).
Alfe
También funciona con variables al final de las líneaslongStr = "account: " + account_id + \ ...
frmbelz
Estoy consiguiendo el error siguiente: the backslash is redundant between bracketscuando escribí en el interiorprint()
Alper
50

Me encontré feliz con este:

string = """This is a
very long string,
containing commas,
that I split up
for readability""".replace('\n',' ')
Eero Aaltonen
fuente
32
Discrepar. ¿Qué sucede si la primera línea ("cadena = ...") está muy sangrada? Uno tendría que eliminar las siguientes líneas a una sangría cero, que se ve fea en el medio de un bloque de otra manera sangrado.
xjcl
1
Bueno, la mayoría de mis cadenas largas ocurren en el nivel del módulo, donde esto encaja muy bien. En su caso, aunque obviamente esta no sería la mejor solución.
Eero Aaltonen
1
Me gusta este enfoque porque privilegia la lectura. En los casos en que tenemos cadenas largas no hay forma ... Dependiendo del nivel de sangría en el que se encuentre y aún limitado a 80 caracteres por línea ... Bueno ... No es necesario decir nada más. Desde mi punto de vista, las guías de estilo Python siguen siendo muy vagas. ¡Gracias!
Eduardo Lucio
Esto sería tan feo si se utiliza en un módulo, tengo que como también.replace('\t','')
Alper
44

Encuentro que al construir cadenas largas, generalmente está haciendo algo como construir una consulta SQL, en cuyo caso esto es lo mejor:

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

Lo que Levon sugirió es bueno, pero podría ser vulnerable a los errores:

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

query == "SELECT fooFROM barWHERE baz"  # probably not what you want
darkfeline
fuente
8
+1 Alivia al revisor de código de tener que verificar asiduamente el extremo derecho de cada línea en busca de espacios en blanco inadecuados . El OP cometió este error varias veces, como lo señaló @KarolyHorvath.
Bob Stein
2
Al revisar cadenas multilínea codificadas de manera similar, necesito un espacio en blanco adecuado en el extremo izquierdo de cada línea para una fácil confirmación.
Paraguas
3
@ Las revisiones del Código BobStein-VisiBone no deberían ser sobre errores de sintaxis o pequeños errores como este, deberían ser sobre la sustancia. Si alguien está poniendo código para revisión que tiene errores de sintaxis (y por lo tanto no se ejecutará en absoluto o en ciertas situaciones), entonces algo está muy mal. No es difícil ejecutar pelusa antes de comprometerse. Si la persona no se ha dado cuenta de que su programa no se ejecuta correctamente porque cometió un error tan obvio, no debería comprometerse.
Charles Addis
1
De acuerdo con @CharlesAddis, las revisiones de código deben venir después de métodos automatizados, por ejemplo, pelusa, resaltado de sintaxis, etc. Sin embargo, algunos errores que faltan espacios en blanco pueden no detectarse de esa manera. Aproveche todas las ventajas razonables para protegerse contra errores, sugiero.
Bob Stein
33

También puede concatenar variables cuando usa la notación "" ":

foo = '1234'

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

EDITAR: Se encontró una mejor manera, con params con nombre y .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)
gjgjgj
fuente
26

Este enfoque utiliza:

  • solo una barra invertida para evitar un salto de línea inicial
  • casi sin puntuación interna mediante el uso de una cadena entre comillas triples
  • elimina la sangría local utilizando el módulo textwrap inspect
  • utiliza la interpolación de cadenas con formato python 3.6 ('f') para las variables account_idy def_id.

De esta manera me parece lo más pitónico.

# 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}'''
)

Actualización : 29/01/2019 Incorpore la sugerencia de @ ShadowRanger de usar en inspect.cleandoclugar detextwrap.dedent

Christopher Bruns
fuente
55
Nota: inspect.cleandoces un poco más bonitas que textwrap.dedent, ya que no requiere la primera línea a estar vacío con un carácter de continuación de línea al final.
ShadowRanger
2
@ShadowRanger Wow Nunca he usado cleandoc antes. Actualicé mi respuesta y lo usaré en el futuro inspect.cleandocpara esto.
Christopher Bruns el
23

En Python> = 3.6 puede usar literales de cadena formateados (cadena f)

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
fuente
44
¿Cómo funcionaría una cadena f si quisiera registrar el resultado de una cadena de varias líneas y no mostrar las pestañas / espacios del lado izquierdo?
kuanb
77
Aún vulnerable a la inyección SQL
Trenton el
19

Por ejemplo:

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'

Si el valor de la condición debe ser una cadena, puede hacer esto:

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
fuente
13

Encuentro textwrap.dedentlo mejor para cadenas largas como se describe aquí :

def create_snippet():
    code_snippet = textwrap.dedent("""\
        int main(int argc, char* argv[]) {
            return 0;
        }
    """)
    do_something(code_snippet)
fredrik
fuente
1
Me gusta la barra negra que impide la nueva línea automática, ¡muchas gracias!
zyy
12

Otros ya han mencionado el método de paréntesis, pero me gustaría agregar que con paréntesis, se permiten comentarios en línea.

Comente sobre cada fragmento:

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.
)

Comentario no permitido después de la continuación:

Cuando se usan continuaciones de línea de barra diagonal inversa ( \), no se permiten comentarios. Recibirás un SyntaxError: unexpected character after line continuation charactererror.

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

Mejores comentarios para las cadenas Regex:

Según el ejemplo de 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
fuente
10

Personalmente, considero que la siguiente es la mejor manera (simple, segura y Pythonic) de escribir consultas SQL sin procesar en Python, especialmente cuando se usa el módulo sqlite3 de Python :

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

Pros

  • Código limpio y simple (Pythonic!)
  • Seguro de inyección SQL
  • Compatible con Python 2 y Python 3 (después de todo, es Pythonic)
  • No se requiere concatenación de cadenas
  • No es necesario asegurarse de que el carácter más a la derecha de cada línea sea un espacio

Contras

  • Dado que las variables en la consulta son reemplazadas por el ?marcador de posición, puede ser un poco difícil hacer un seguimiento de cuál ?será sustituido por qué variable de Python cuando hay muchas de ellas en la consulta.
Faheel
fuente
Tenga en cuenta que no he probado esto, pero probablemente pueda evitar la confusión del signo de interrogación al reemplazarlos con "{0} {1} {2}" en los lugares relevantes y luego cambiar la última línea a cursor.execute(query.format(vars)). Eso debería encargarse de su única "estafa" (espero).
Ben
Sí, usar formatsería bueno, pero no estoy seguro de si la cadena de consulta formateada de esa manera estaría a salvo de la inyección de SQL.
Faheel
Sí, ese es un punto justo y ciertamente podría ser un poco complicado. Quizás sería prudente probarlo en algo totalmente prescindible ... sin duda, un Comp. Sci. Pregrado vagará pronto lo suficiente. ;)
Ben
2
@Ben, si lo hace, cursor.execute(query.format(vars))ya no se beneficia de las declaraciones preparadas, por lo que es vulnerable a muchos tipos de problemas, comenzando con el hecho de que si los parámetros no son solo números, debe citarlos dos veces en la consulta SQL.
Patrick Mevzek
4

Usualmente uso algo como esto:

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

Si desea eliminar espacios en blanco molestos en cada línea, puede hacer lo siguiente:

text = '\n'.join(line.lstrip() for line in text.splitlines())
Israel Barth Rubio
fuente
2
Mire la textwrap.dedentfunción de Python , que está en la biblioteca estándar, tiene la funcionalidad que necesita.
bjd2385 21/0618
@ bjd2385: inspect.cleandoces un poco más agradable (menos quisquilloso sobre si el texto aparece o no en la misma línea que las comillas abiertas, no requiere caracteres de continuación de línea explícitos).
ShadowRanger
3

Su código real no debería funcionar, le faltan espacios en blanco al final de las "líneas" (por ejemplo: role.descr as roleFROM... )

Hay comillas triples para cadenas multilínea:

string = """line
  line2
  line3"""

Contendrá los saltos de línea y espacios adicionales, pero para SQL eso no es un problema.

Karoly Horvath
fuente
3

También puede colocar la instrucción sql en un archivo separado action.sqly cargarlo en el archivo py con

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

Entonces las sentencias sql se separarán del código de Python. Si hay parámetros en la instrucción sql que deben completarse desde python, puede usar el formateo de cadenas (como% so {campo})

mrijken
fuente
3

Forma "À la" Scala (pero creo que es la forma más pitónica que exige OQ):

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('            | ',' ')

Si desea str final sin líneas de salto, simplemente coloque \nal comienzo del primer argumento del segundo reemplazo:

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

Nota: la línea blanca entre "... plantillas". y "Además, ..." requiere un espacio en blanco después de |.

victe
fuente
3

tl; dr: Use """\y """para envolver la cadena , como en

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

De la documentación oficial de Python :

Los literales de cadena pueden abarcar varias líneas. Una forma es usar comillas triples: "" "..." "" o '' '...' ''. El final de las líneas se incluye automáticamente en la cadena, pero es posible evitar esto agregando un \ al final de la línea. El siguiente ejemplo:

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

produce el siguiente resultado (tenga en cuenta que la nueva línea inicial no está incluida):

Usage: thingy [OPTIONS]
     -h                        Display this usage message
     -H hostname               Hostname to connect to
Fluir
fuente
2

Oye, prueba algo como esto, espero que funcione, como en este formato te devolverá una línea continua como si hubieras preguntado con éxito sobre esta propiedad '

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

Utilizo una función recursiva para construir consultas SQL complejas. Esta técnica generalmente se puede usar para construir cadenas grandes mientras se mantiene la legibilidad del código.

# 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)

PD: Eche un vistazo a la impresionante biblioteca python-sqlparse para imprimir bonitas consultas SQL si es necesario. http://sqlparse.readthedocs.org/en/latest/api/#sqlparse.format

Sandeep
fuente
"función recursiva" no se llama lambda?
m3nda
1

Otra opción que creo que es más legible cuando el código (por ejemplo, la variable) está sangrado y la cadena de salida debe ser un trazador de líneas (sin líneas nuevas):

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
fuente
1

Use comillas triples. La gente a menudo los usa para crear cadenas de documentos al comienzo de los programas para explicar su propósito y otra información relevante para su creación. Las personas también usan estos en funciones para explicar el propósito y la aplicación de funciones. Ejemplo:

'''
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
fuente
0

Me gusta este enfoque porque privilegia la lectura. ¡En casos donde tenemos cuerdas largas no hay forma! Dependiendo del nivel de sangría en el que se encuentre y aún limitado a 80 caracteres por línea ... Bueno ... No es necesario decir nada más. Desde mi punto de vista, las guías de estilo Python siguen siendo muy vagas. Tomé el enfoque @Eero Aaltonen porque privilegia la lectura y el sentido común. Entiendo que las guías de estilo deberían ayudarnos y no hacer que nuestras vidas sean un desastre. ¡Gracias!

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
fuente
0

De la documentación oficial de Python :

Los literales de cadena pueden abarcar varias líneas. Una forma es usar comillas triples: "" "..." "" o '' '...' ''. El final de las líneas se incluye automáticamente en la cadena, pero es posible evitar esto agregando un \ al final de la línea. El siguiente ejemplo:

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

produce el siguiente resultado (tenga en cuenta que la nueva línea inicial no está incluida):

Fluir
fuente
0

Para definir una cadena larga dentro de un dict, manteniendo las nuevas líneas pero omitiendo los espacios , terminé definiendo la cadena en una constante como esta:

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

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

Como enfoque general para cadenas largas en Python, puede usar comillas triples splity 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())

Salida:

'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.'

Con respecto a la pregunta de OP relacionada con una consulta SQL, la respuesta a continuación ignora la exactitud de este enfoque para crear consultas SQL y se centra solo en construir cadenas largas de una manera legible y estética sin importaciones adicionales. También ignora la carga computacional que esto conlleva.

Usando comillas triples, construimos una cadena larga y legible que luego dividimos en una lista usando, de split()ese modo, eliminamos el espacio en blanco y luego lo unimos nuevamente ' '.join(). Finalmente insertamos las variables usando el format()comando:

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)

Produce:

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

Editar: este enfoque no está en línea con PEP8, pero a veces me resulta útil

Rasmus Groth
fuente
-7

En general, uso listy joinpara comentarios / cadenas de varias líneas.

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)

puede usar cualquier cadena para unir todo este elemento de la lista como ' \n' (nueva línea) o ' ,' (coma) o ' ' (espacio)

Salud..!!

paone
fuente
1
¿Por qué al menos no usarías una matriz literal?
Alexander - Restablece a Monica el
1
Las matrices se representan por lista de clases.
Echa un
Supongo que esto funciona, pero deberías pensar en el rendimiento y la legibilidad ...
Petro