¿Cómo puedo romper esta larga línea en Python?


¿Cómo dar formato a una línea larga como esta? Me gustaría que no tuviera más de 80 caracteres de ancho:

logger.info("Skipping {0} because its thumbnail was already in our system as {1}.".format(line[indexes['url']], video.title))

¿Es esta mi mejor opción?

url = "Skipping {0} because its thumbnail was already in our system as {1}."
logger.info(url.format(line[indexes['url']], video.title))
Author: Gattster, 2010-01-13

4 answers

Eso es un comienzo. No es una mala práctica definir tus cadenas más largas fuera del código que las usa. Es una forma de separar los datos y el comportamiento. Su primera opción es unir literales de cadena implícitamente haciéndolos adyacentes entre sí:

("This is the first line of my text, "
"which will be joined to a second.")

O con continuaciones de terminación de línea, que es un poco más frágil, ya que esto funciona:

"This is the first line of my text, " \
"which will be joined to a second."

Pero esto no:

"This is the first line of my text, " \ 
"which will be joined to a second."

¿Ves la diferencia? ¿No? Bueno, no lo harás cuando sea tu código bien.

La desventaja de la unión implícita es que solo funciona con literales de cadena, no con cadenas tomadas de variables, así que las cosas pueden ponerse un poco más peludas cuando refactorizas. Además, solo puede interpolar el formato en la cadena combinada como un todo.

Alternativamente, puede unirse explícitamente usando el operador de concatenación(+):

("This is the first line of my text, " + 
"which will be joined to a second.")

Lo explícito es mejor que lo implícito, como dice el zen de python, pero esto crea tres cadenas en lugar de una, y usa el doble de memoria: están los dos que has escrito, más uno que son los dos juntos, así que tienes que saber cuándo ignorar el zen. La ventaja es que puede aplicar formato a cualquiera de las subcadenas por separado en cada línea, o a todo el lote desde fuera de los paréntesis.

Finalmente, puedes usar cadenas de texto entre comillas triples:

"""This is the first line of my text
which will be joined to a second."""

Este es a menudo mi favorito, aunque su comportamiento es ligeramente diferente como la nueva línea y cualquier espacio en blanco inicial en las líneas posteriores se mostrará en su cadena final. Puede eliminar la nueva línea con una barra invertida de escape.

"""This is the first line of my text \
which will be joined to a second."""

Esto tiene el mismo problema que la misma técnica anterior, en que el código correcto solo difiere del código incorrecto por espacios en blanco invisibles.

Cuál es "mejor" depende de su situación particular, pero la respuesta no es simplemente estética, sino una de comportamientos sutilmente diferentes.

 248
Author: jcdyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-13 17:59:25

Los literales de cadena consecutivos se unen por el compilador, y las expresiones entre paréntesis se consideran una sola línea de código:

logger.info("Skipping {0} because it's thumbnail was "
  "already in our system as {1}.".format(line[indexes['url']],
  video.title))
 30
Author: Ignacio Vazquez-Abrams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-13 17:43:47

Personalmente no me gusta colgar bloques abiertos, así que lo formatearía como:

logger.info(
    'Skipping {0} because its thumbnail was already in our system as {1}.'
    .format(line[indexes['url']], video.title)
)

En general, no me molestaría en luchar demasiado duro para hacer que el código quepa exactamente dentro de una línea de 80 columnas. Vale la pena mantener la longitud de la línea a niveles razonables, pero el límite de 80 es una cosa del pasado.

 8
Author: bobince,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-13 17:58:10

Puede usar el módulo textwrap para dividirlo en varias líneas

import textwrap
str="ABCDEFGHIJKLIMNO"
print("\n".join(textwrap.wrap(str,8)))

ABCDEFGH
IJKLIMNO

De la documentación :

Textwrap.wrap(texto[, ancho[, ...]])
Envuelve el párrafo único en texto (una cadena) para que cada línea tenga como máximo caracteres de ancho. Devuelve una lista de líneas de salida, sin nuevas líneas finales.

Los argumentos de palabras clave opcionales corresponden a los atributos de instancia de TextWrapper, documentado a continuación. el valor predeterminado de width es 70.

Ver el TextWrapper.wrap() método para obtener detalles adicionales sobre cómo se comporta wrap ().

 3
Author: Saurabh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-23 17:20:56