Envolver líneas largas en Python [duplicate]

8 minutos de lectura

avatar de usuario
usuario225312

¿Cómo envuelvo líneas largas en Python sin sacrificar la sangría?

Por ejemplo:

def fun():
    print '{0} Here is a really long sentence with {1}'.format(3, 5)

Supongamos que esto supera el límite recomendado de 79 caracteres. La forma en que lo leí, aquí está cómo sangrar:

def fun():
    print '{0} Here is a really long \
sentence with {1}'.format(3, 5)

Sin embargo, con este enfoque, la sangría de la línea continua coincide con la sangría de la fun(). Esto se ve un poco feo. Si alguien revisara mi código, se vería mal tener una sangría desigual debido a esto print declaración.

¿Cómo sangro líneas como esta de manera efectiva sin sacrificar la legibilidad del código?

  • También eche un vistazo a esta pregunta relacionada: stackoverflow.com/questions/53162/…

    – Pierz

    2 oct 2013 a las 14:03

avatar de usuario
pv2b

def fun():
    print(('{0} Here is a really long '
           'sentence with {1}').format(3, 5))

Los literales de cadena adyacentes se concatenan en tiempo de compilación, al igual que en C. http://docs.python.org/reference/lexical_analysis.html#string-literal-concatenation es un buen lugar para comenzar para obtener más información.

  • En realidad, el “\” es redundante y se puede omitir.

    – Daniel Rey

    7 de enero de 2013 a las 17:19


  • @DanielReis No estoy seguro de que eso sea cierto para todas las plataformas o distribuciones de Python. Recibí un resultado de un usuario donde no se imprimió todo lo que estaba después de la primera línea. Mi código era como el anterior, sin barra invertida.

    – BHSPitMonkey

    1 de julio de 2013 a las 18:49

  • Las cadenas Unicode necesitan la barra invertida en python 2.x

    – gipaetus

    7 julio 2013 a las 22:30

  • Dentro de los paréntesis, la continuación de la línea está implícita, por lo que + en cambio basta. Tenga en cuenta que evitar los paréntesis dificulta la portabilidad a Python 3.x, imagine un código cuya única necesidad de 2to3 son print declaraciones, pero de lo contrario no requeriría ninguna conversión.

    – 0 _

    10 de agosto de 2013 a las 8:17

  • @MigueldeVal-Borro, el motivo de su comentario es incorrecto: se necesita la barra invertida porque el salto de línea no está entre un par de paréntesis (o corchetes, …). Es decir, las cadenas de bytes también necesitan la barra invertida.

    – Roberto Siemer

    13 de abril de 2016 a las 16:22

avatar de usuario
0 _

Usando concatenación de literales de cadena adyacentesJuntos con literales de cadena con formato es el camino a seguir:

x = 2
sep = 2 * '\n'
print(
    'This message is so long that it requires '
    f'more than {x} lines.{sep}'
    'And more lines may be needed.')

Este enfoque cumple con PEP 8 y permite un mejor aprovechamiento del espacio.

No + Se necesitan operadores, sin barras invertidas para la continuación de la línea, sin irregularidades de sangría, sin tendencia a errores. += a una variable de cadena acumuladora (que se puede escribir incorrectamente como =lo que resulta en un error silencioso), sin paréntesis sueltos colgando debajo del print (los argumentos se colocan en su propio nivel de sangría, y el siguiente elemento en el nivel de sangría de print es la siguiente afirmación).

Comenzando las cadenas en la línea debajo de la línea que contiene el print( reduce la sangría y es más legible. La legibilidad proviene de ambos print( destacándose, por estar en su propia línea, y por la alineación uniforme de enunciados consecutivos de esta forma.

La reducción de la sangría de este enfoque se vuelve más evidente cuando se generan excepciones:

raise ModuleNotFoundError(
    'aaaaaaaaaaaaaaaaaaaaaaaa'
    'aaaaaaaaaaaaaaaaaaaaaaaa'
    f'aaaaa {x} aaaaa')

Con respecto a los literales de cadena formateados (representados por el prefijo “f”, como en f'...'), cuerdas en bruto pueden ser literales de cadena formateadoscombinando los prefijos “r” y “f”:

rf'This is a formatted raw string, {sep}here is a backslash \.'

Tenga en cuenta que las cadenas sin procesar son necesarias para incluir barras invertidas literales sin escribir \\. De lo contrario, en una versión futura de CPython, un SyntaxError será levantado. A partir de Python 3.9, un DeprecationWarning es elevado:

python -X dev -c '"\q"'

salidas:

<string>:1: DeprecationWarning: invalid escape sequence \q

Los reemplazos son muy legibles. En particular, este enfoque hace que escribir código que genere código o fórmulas matemáticas sea una tarea muy agradable.

En raras ocasiones, el método str.format puede ser adecuado, debido a las sustituciones que se necesitan. Se puede utilizar de la siguiente manera:

print((
    'This message is so long that it requires '
    'more than {x} lines.{sep}'
    'And more lines may be needed.'
    ).format(x=x, sep=sep))

  • ¿Tiene alguna desventaja (primera aproximación)? Porque para mí es mucho mejor que otros.

    – antonavi

    2 de diciembre de 2015 a las 19:16


  • Mi experiencia con él hasta ahora dice que no tiene ningún inconveniente. Es un patrón muy legible para todo clima que se puede usar en todas partes, desde mensajes hasta backends del compilador.

    – 0 _

    2 de diciembre de 2015 a las 20:13

  • ¿La solución PEP 8 hará que se introduzcan saltos de línea si tengo la intención de poner este texto en un .csv archivo u otro formato de archivo de salida además del terminal? Mi temor es que tendré muchas líneas cuando esperaba solo 1.

    – Chris

    28 de junio de 2016 a las 13:55

  • No hay saltos de línea aparte de los explícitos. \n presentado por sep (solo define sep diferentemente). Las cadenas simplemente se concatenan.

    – 0 _

    28/06/2016 a las 21:40

Puede usar el siguiente código donde la sangría no importa:

>>> def fun():
        return ('{0} Here is a really long'
        ' sentence with {1}').format(3, 5)

Solo necesita encerrar la cadena entre paréntesis.

  • Gracias. Esto debería funcionar para mí.

    – usuario225312

    27 de julio de 2010 a las 17:43

  • Advertencia para los novatos de Python: este código no cumple con PEP8 y no debe sangrarse de esta manera.

    – glarraín

    19 de julio de 2013 a las 17:48

Puede usar el hecho de que Python concatena literales de cadena que aparecen uno al lado del otro:

>>> def fun():
...     print '{0} Here is a really long ' \
...           'sentence with {1}'.format(3, 5)

avatar de usuario
marca byers

Probablemente dividiría la declaración larga en varias declaraciones más cortas para que la lógica del programa se separe de la definición de la cadena larga:

>>> def fun():
...     format_string = '{0} Here is a really long ' \
...                     'sentence with {1}'
...     print format_string.format(3, 5)

Si la cadena es demasiado larga y elige un nombre de variable corto, al hacer esto puede incluso evitar tener que dividir la cadena:

>>> def fun():
...     s="{0} Here is a really long sentence with {1}"
...     print s.format(3, 5)

  • Sí, también había considerado este enfoque. De hecho, es viable.

    – usuario225312

    27 de julio de 2010 a las 17:44

  • En realidad perdiéndome el + funcionaría aquí también, como lo señalan las otras respuestas y sería una mejora para mi respuesta. La diferencia entre mi respuesta y las demás es que no estoy tratando de hacer todo en una declaración. Creo que ayuda a la legibilidad dividir declaraciones largas en varias más cortas.

    –Mark Byers

    27 de julio de 2010 a las 17:45


  • El único inconveniente de esto sería que tengo que declarar una cadena separada para esto. No tengo ningún problema con eso, pero supongo que el enfoque de paréntesis debería funcionar, en mi opinión.

    – usuario225312

    27 de julio de 2010 a las 17:47

  • Como ya aceptaste, actualicé mi respuesta para incluir la idea de la respuesta aceptada.

    –Mark Byers

    27/07/2010 a las 18:00

  • Sí, había considerado seriamente su enfoque, pero luego decidí preguntar aquí. Dado que la impresión y el formato ocupan espacio, esto funciona.

    – usuario225312

    27 de julio de 2010 a las 18:08


avatar de usuario
Taylor D Edmiston

Me sorprende que nadie haya mencionado el estilo implícito anterior. Mi preferencia es usar paréntesis para envolver la cuerda mientras la alinea visualmente. Personalmente, creo que esto se ve más limpio y compacto que comenzar el comienzo de la cadena en una nueva línea con pestañas.

Tenga en cuenta que estos paréntesis no son parte de una llamada de método, solo son concatenación literal de cadena implícita.

Pitón 2:

def fun():
    print ('{0} Here is a really '
           'long sentence with {1}').format(3, 5)

Python 3 (con paréntesis para la función de impresión):

def fun():
    print(('{0} Here is a really '
           'long sentence with {1}').format(3, 5))

Personalmente, creo que es más limpio separar la concatenación del literal de cadena larga de la impresión:

def fun():
    s = ('{0} Here is a really '
         'long sentence with {1}').format(3, 5)
    print(s)

  • Sí, también había considerado este enfoque. De hecho, es viable.

    – usuario225312

    27 de julio de 2010 a las 17:44

  • En realidad perdiéndome la + funcionaría aquí también, como lo señalan las otras respuestas y sería una mejora para mi respuesta. La diferencia entre mi respuesta y las demás es que no estoy tratando de hacer todo en una declaración. Creo que ayuda a la legibilidad dividir declaraciones largas en varias más cortas.

    –Mark Byers

    27 de julio de 2010 a las 17:45


  • El único inconveniente de esto sería que tengo que declarar una cadena separada para esto. No tengo ningún problema con eso, pero supongo que el enfoque de paréntesis debería funcionar, en mi opinión.

    – usuario225312

    27 de julio de 2010 a las 17:47

  • Como ya aceptaste, actualicé mi respuesta para incluir la idea de la respuesta aceptada.

    –Mark Byers

    27/07/2010 a las 18:00

  • Sí, había considerado seriamente su enfoque, pero luego decidí preguntar aquí. Dado que la impresión y el formato ocupan espacio, esto funciona.

    – usuario225312

    27 de julio de 2010 a las 18:08


¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad