Strings com várias linhas em Python

Recentemente, tive que preparar uma string com várias linhas, contendo o cabeçalho de um e-mail em um programa escrito em Python. Até aí, nenhuma novidade: bastava usar as três aspas para indicar o início e mais três para indicar o fim da string. No entanto, a string estava localizada em um bloco com indentação, o que fez com que a indentação ficasse incluída no conteúdo da string. Para entender melhor o que aconteceu, segue um exemplo:

def funcao():
    mensagem =  """From: admin@provedor.com.br
    To: destinatario@provedor.com.br
    Subject: Importante

    Aqui vai uma mensagem importante.
    """

    print mensagem

Chamando essa função no interpretador Python, vem o seguinte resultado:

>>> funcao()
From: admin@provedor.com.br
    To: destinatario@provedor.com.br
    Subject: Importante

    Aqui vai uma mensagem importante.

Como pode ser observado, da segunda linha em diante, a string acaba incluindo as indentações usadas no bloco de código.

O motivo desse comportamento é fácil de ser identificado, já que os espaços em branco estão de fato incluídos na string :-). No entanto, em alguns casos, como no caso de cabeçalhos de e-mail, é necessário que as strings não possuam caracteres em branco no início das linhas, caso contrário o cabeçalho não é interpretado corretamente pelos servidores de e-mail. Nesse caso, a forma mais fácil de corrigir o problema é remover os espaços iniciais da string:

def funcao():
    mensagem =  """From: admin@provedor.com.br
To: destinatario@provedor.com.br
Subject: Importante

Aqui vai uma mensagem importante.
"""

    print mensagem

Com essa alteração, o resultado esperado é obtido no teste com o interpretador:

>>> funcao()
From: admin@provedor.com.br
To: destinatario@provedor.com.br
Subject: Importante

Aqui vai uma mensagem importante.

No entanto, o código ficaria muito mais legível (e mais bonito :-P) se fosse possível resolver o problema mantendo a indentação da string. Para isso, pode-se usar a função dedent do módulo textwrap:

from textwrap import dedent

def funcao():
    mensagem =  dedent("""\
    From: admin@provedor.com.br
    To: destinatario@provedor.com.br
    Subject: Importante

    Aqui vai uma mensagem importante.
    """)

    print mensagem

A função dedent remove os caracteres de indentação comuns à todas as linhas de uma string. Nesse caso, como todas as linhas possuem quatro espaços iniciais, eles são removidos. Como o dedent só remove a indentação que é comum à todas as linhas, as linhas em branco também devem conter a indentação (como a linha 8). Além disso, vale notar que a primeira linha da string foi deslocada para baixo pare que todas as linhas ficassem com o mesmo espaço de indentação inicial. Com isso, a string acaba sendo iniciada por uma quebra de linha, o que geralmente não é desejado. Para contornar esse problema, foi incluída a barra inversa no início, que serve para fazer com que o caractere seguinte a ela seja ignorado (a quebra de linha).

Com isso, é obtido o resultado esperado:

>>> funcao()
From: admin@provedor.com.br
To: destinatario@provedor.com.br
Subject: Importante

Aqui vai uma mensagem importante.

Apesar do resultado ser o mesmo, acho que vale o trabalho de usar a função dedent para tornar o código mais legível. Para saber mais, veja a página de documentação do textwrap.

Comentários

Deixe um comentário

XHTML: Você pode usar as tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>