Como posso quebrar essa longa linha no Python?

176

Como você formata uma linha longa como essa? Eu gostaria de ter no máximo 80 caracteres de largura:

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

Essa é a minha melhor opção?

url = "Skipping {0} because its thumbnail was already in our system as {1}."
logger.info(url.format(line[indexes['url']], video.title))
Gattster
fonte
1
Parece uma boa opção. O que você não gosta nisso?
Hamish Grubijan
2
Um pouco subjetivo, não é? :)
Adam Woś
1
Para
saber mais
14
Você pode salvar um personagem removendo o incorreto 'em "é".
jball
2
indexes: o plural correto de indexé indices.
Scruffy

Respostas:

336

Isso é um começo. Não é uma prática ruim definir suas seqüências mais longas fora do código que as usa. É uma maneira de separar dados e comportamento. Sua primeira opção é unir literais de cadeia implicitamente, tornando-os adjacentes um ao outro:

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

Ou com continuações de final de linha, que são um pouco mais frágeis, pois isso funciona:

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

Mas isso não acontece:

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

Veja a diferença? Não? Bem, você não vai quando é o seu código também.

A desvantagem da junção implícita é que ela só funciona com literais de strings, não com strings de variáveis, para que as coisas fiquem um pouco mais peludas quando você refatorar. Além disso, você só pode interpolar a formatação na cadeia combinada como um todo.

Como alternativa, você pode ingressar explicitamente usando o operador de concatenação ( +):

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

Explícito é melhor do que implícito, como diz o zen do python, mas isso cria três strings em vez de um e usa o dobro de memória: existem as duas que você escreveu, mais uma que são as duas juntas, então você tem que saber quando ignorar o zen. A vantagem é que você pode aplicar a formatação a qualquer uma das substrings separadamente em cada linha ou a todo o lote de fora dos parênteses.

Por fim, você pode usar cadeias de caracteres triplas:

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

Geralmente, é o meu favorito, embora seu comportamento seja ligeiramente diferente, pois a nova linha e qualquer espaço em branco à esquerda nas linhas subseqüentes aparecerão na sua sequência final. Você pode eliminar a nova linha com uma barra invertida de escape.

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

Isso tem o mesmo problema que a mesma técnica acima, pois o código correto difere apenas do código incorreto pelo espaço em branco invisível.

Qual é o "melhor" depende da sua situação específica, mas a resposta não é simplesmente estética, mas um comportamento sutilmente diferente.

jcdyer
fonte
26
O compilador CPython otimiza as operações literais o máximo possível, o que significa que a adição de dois literais de cadeia resulta em apenas uma única cadeia de caracteres literal no bytecode.
Ignacio Vazquez-Abrams
2
Embora todas as respostas que recebi sejam úteis, as suas definitivamente me ajudam a entender todas as maneiras de quebrar as cordas. O problema com a linha "\" terminava porque havia um espaço depois dela?
Gattster 13/01/10
1
Não vejo a diferença aqui, mas é principalmente por causa da coloração de sintaxe bastante primitiva do SO. (Algum código perfeitamente bom é praticamente ilegível no SO, mas apenas porque ele não está em um idioma cuja sintaxe é muito próxima de C.) . :-)
Ken
1
@KhurshidAlam, você pode usar aspas simples 'para conter essa sequência ou escapar das aspas duplas dentro de sua sequência ou usar aspas duplas triplas """. O problema com seqüências de caracteres entre aspas contendo aspas é o mesmo, se você usa uma única linha ou várias linhas para definir a sequência literal.
hugovdberg
1
Meu editor remove sempre os espaços em branco à direita. Eu recomendo que você ative a mesma configuração. Claro que o espaço em branco na nova linha ainda faz parte da string, então acabei usando +.
ThaJay 18/10/19
46

Literais consecutivos de sequência são unidos pelo compilador e expressões entre parênteses são consideradas uma única linha de código:

logger.info("Skipping {0} because it's thumbnail was "
  "already in our system as {1}.".format(line[indexes['url']],
  video.title))
Ignacio Vazquez-Abrams
fonte
11

Pessoalmente, eu não gosto de pendurar blocos abertos, então eu o formataria como:

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

Em geral, eu não me incomodaria muito em fazer o código se encaixar exatamente dentro de uma linha de 80 colunas. Vale a pena manter o comprimento da linha em níveis razoáveis, mas o limite dos 80 é uma coisa do passado.

bobince
fonte
8
Não é realmente uma coisa do passado. A biblioteca padrão do Python ainda usa o PEP8 como guia de estilo, portanto a regra ainda existe e muitas pessoas (inclusive eu) a seguem. É um lugar conveniente para traçar a linha.
Devin Jeanpierre
3
Gostaria de saber quantos projetos ainda seguem a regra dos 80 caracteres. Para o tamanho médio da janela que eu uso, acho que 100-120 é mais produtivo para mim do que 80 caracteres.
Gattster 14/01/10
1
Sim, é sobre o comprimento da linha que eu também uso, [horror! sacrilégio!] Eu uso uma fonte proporcional, para que o comprimento exato da linha não seja tão crítico. É mais um caso de quanta lógica em uma única linha é legível do que quantos caracteres, como tal ... se eu tenho uma longa sequência de dados que ninguém precisa ler, fico feliz em deixá-la transbordar 120.
bobince
Fontes proporcionais para código - estou com você, irmão. A julgar pelo desgosto que todos com quem já trabalhei tiveram por eles, o mundo não está pronto.
precisa saber é o seguinte
4
~ 80 caracteres também facilitam a difusão de 2 arquivos lado a lado na mesma tela. Além disso, se você estiver depurando algo durante uma emergência terrível no console de um servidor, realmente apreciará o limite de 80 caracteres! :)
Mick T
4

Você pode usar o módulo textwrap para quebrá-lo em várias linhas

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

ABCDEFGH
IJKLIMNO

A partir da documentação :

embrulho de texto. quebra automática (texto [, largura [, ...]])
Agrupa o parágrafo único no texto (uma sequência) para que cada linha tenha no máximo caracteres de largura. Retorna uma lista de linhas de saída, sem novas linhas finais.

Os argumentos opcionais da palavra-chave correspondem aos atributos da instância TextWrapperdocumentados abaixo. o padrão da largura é 70.

Veja o TextWrapper.wrap()método para obter detalhes adicionais sobre como o wrap () se comporta.

Saurabh
fonte
2

Para quem também está tentando chamar .format()uma cadeia longa e não pode usar algumas das técnicas mais populares de quebra de cadeia sem interromper a .format(chamada subsequente , você pode fazer isso em str.format("", 1, 2)vez de "".format(1, 2). Isso permite que você quebre a corda com qualquer técnica que desejar. Por exemplo:

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

pode ser

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

Caso contrário, a única possibilidade é usar continuações de final de linha, das quais pessoalmente não sou fã.

Simon Alford
fonte