Pregunta Manera pitónica de crear una larga cadena de múltiples líneas


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 lectura de 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 utilicé \ para dividir la cadena larga. Sin embargo, no estoy seguro de si esta es la única forma / mejor / pythonicest de hacerlo. Se ve incomodo. 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

778
2018-05-18 22:21


origen


Respuestas:


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

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 al principio y al final) y tratar la cadena resultante s al igual que cualquier otra cadena.

NOTA: Al igual que con cualquier cadena, cualquier cosa entre las comillas inicial y final 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, también se pueden construir largas líneas en Python como esta:

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

que lo hará no incluya espacios en blanco adicionales o líneas nuevas (este es un ejemplo deliberado que muestra el resultado del salto de espacios en blanco):

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

No se requieren comas, simplemente coloque las cadenas para unirlas en un par de paréntesis y asegúrese de dar cuenta de los espacios en blanco y líneas nuevas necesarios.


1335
2018-05-18 22:22



Si no desea una cadena de línea múltiple, 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 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ás 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.


125
2018-05-18 22:26



Rompiendo líneas por \ funciona para mi. 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"

100
2018-06-20 16:16



Me encontré feliz con este:

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

34
2018-01-04 10:39



Encuentro que al construir cadenas largas, generalmente se está haciendo algo así como crear 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

27
2018-06-19 07:06



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: Encontré una mejor manera, con params nombrados 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)

20
2017-10-06 22:33



En Python> = 3.6 puedes 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}'''

14
2018-04-25 18:47



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

8
2018-05-12 12:05



Personalmente encuentro lo siguiente para ser la mejor (simple, segura y pitonica) forma de escribir consultas RAW en Python, especialmente cuando se usa 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 desde la inyección de 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 ? marcador de posición, puede ser un poco difícil hacer un seguimiento de qué ? debe ser sustituido por la variable de Python cuando hay muchos de ellos en la consulta.

5
2017-11-14 19:16



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

Hay triplequotes para cadena multilínea:

string = """line
  line2
  line3"""

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


3
2018-05-18 22:25



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.split('\n')])

3
2018-06-21 17:36