Anular problemas de contrabarra do Windows com as cordas cruas de Python

Eu sou um tipo Unix, mas os participantes das minhas aulas de Python usam o Windows de forma esmagadora. Inevitavelmente, quando falamos em trabalhar com arquivos em Python, alguém vai querer abrir um arquivo usando o caminho completo para o arquivo. E eles vão acabar escrevendo algo assim:

filename = 'c:\abc\def\ghi.txt'

Mas quando meus alunos tentam abrir o arquivo, eles descobrem que o Python lhes dá um erro, indicando que o arquivo não existe! Em outras palavras, eles escrevem:

for one_line in open(filename): print(one_line)

Qual é o problema? Isto parece ser um Python bastante padrão, no?

Lembrar que as strings em Python normalmente contêm caracteres. Esses caracteres são normalmente imprimíveis, mas há momentos em que você quer incluir um caracter que não é realmente imprimível, como uma nova linha. Nesses casos, Python (como muitas linguagens de programação) inclui códigos especiais que irão inserir o caractere especial.

O exemplo mais conhecido é a newline, aka ‘\n’, ou ASCII 10. Se você quiser inserir uma nova linha na sua string Python, então você pode fazer isso com ‘\n’ no meio. Por exemplo:

s = 'abc\ndef\nghi'

Quando imprimimos a string, veremos:

>>> print(s)abcdefghi

E se você quiser imprimir um ‘\n’ literal no seu código? Ou seja, você quer uma barra invertida, seguida de um “n”? Então você precisará dobrar a barra invertida:O “\n” em uma string resultará em um único caractere de barra invertida. O “n” seguinte será então normal. Por exemplo:

s = 'abc\ndef\nghi'

Quando dizemos:

>>> print(s)abc\ndef\nghi

É bem sabido que você tem que se precaver contra esta tradução quando você está trabalhando com \n. Mas que outros caracteres a requerem? Acontece que, mais do que muitas pessoas poderiam esperar:

  • \a – campainha de alarme (ASCII 7)
  • \b – backspace (ASCII
  • \f – feed de formulário
  • \n – newline
  • \r – carriage return
  • \t – tab
  • \v – separador vertical
  • \ooo – caractere com valor octal ooo
  • \xhh – caractere com valor hexadecimal hh
  • \N{nome} – caractere Unicode {nome}
  • \uxxxx – caractere Unicode com 16-bit hex value xxxx
  • \Uxxxxxxxx – Caracteres unicode com valor hexadecimais de 32 bits xxxxxxxx

Na minha experiência, é extremamente improvável que você use alguns destes de propósito. Quero dizer, quando foi a última vez que precisou de usar um carácter de alimentação de formulários? Ou uma aba vertical? Eu sei – foi mais ou menos no mesmo dia em que você levou o seu dinossauro para o trabalho, depois de cavar um poço no seu quintal para beber água.

Mas quase sempre que eu ensino Python – que é, todos os dias – alguém da minha turma choca com um desses personagens por engano. Isso porque a combinação das contrabarras usadas por esses personagens e as contrabarras usadas nos caminhos do Windows torna inevitáveis, e frustrantes, os bugs.

Lembrar aquele caminho que mencionei no topo do post do blog, que parece tão inocente?

filename = 'c:\abc\def\ghi.txt'

Contém um caracter “\a”. O que significa que quando o imprimimos:

>>> print(filename)c:bc\def\ghi.txt

Veja? O “\a” desapareceu, substituído por um caractere de alarme. Se tiveres sorte.

Então, o que podemos fazer em relação a isto? Duplicar as pancadas nas costas, claro. Você só precisa dobrar aqueles que seriam transformados em caracteres especiais, da tabela que eu reproduzi acima: Mas vá lá, é mesmo provável que se lembrem que “f” é especial, mas “g” não é? Provavelmente não.

Então minha regra geral, e o que eu digo aos meus alunos, é que eles devem sempre dobrar as contrabarragens em seus caminhos no Windows. Em outras palavras:

>>> filename = 'c:\abc\def\ghi.txt'>>> print(filename)c:\abc\def\ghi.txt

Funciona!

Mas espere: ninguém quer realmente percorrer os seus caminhos, dobrando cada contrabarra, pois não? Claro que não.

É aí que as cordas cruas de Python podem ajudar. Eu penso em cordas cruas de duas maneiras diferentes:

  • what-you-see-is-what-you-get strings
  • automaticamente duplica as contrabarras em cordas

De qualquer forma, o efeito é o mesmo: todas as contrabarras são duplas, por isso todos estes caracteres especiais chatos e estranhos desaparecem. O que é ótimo quando você está trabalhando com caminhos do Windows.

Tudo que você precisa fazer é colocar um “r” antes das aspas de abertura (simples ou duplo):

>>> filename = r'c:\abc\def\ghi.txt'>>> print(filename)c:\abc\def\ghi.txt

Note que uma “string bruta” não é realmente um tipo diferente de string. É apenas outra forma de inserir uma string em Python. Se você verificar, digite(filename) ainda será “str”, mas suas barras invertidas serão todas dobradas.

Bottom line: Se você estiver usando Windows, então você deve apenas escrever todas as suas strings hard-coded como strings brutas. Mesmo que você seja um especialista em Python, posso dizer por experiência própria que você vai se deparar com este problema às vezes. E mesmo para o melhor de nós, descobrir que o “\f” perdido em uma string pode ser demorado e frustrante.

PS: Sim, é verdade que os usuários do Windows podem contornar isso usando slashes para frente, como nós, o pessoal do Unix, fazemos. Mas meus alunos acham isso particularmente estranho, e por isso eu não vejo isso como uma solução de propósito geral.

Desfrutou deste artigo? Junte-se a mais de 11.000 outros desenvolvedores que recebem minha newsletter semanal gratuita “Melhores desenvolvedores”. Toda segunda-feira, você receberá um artigo como este sobre desenvolvimento de software e Python:

Deixe uma resposta

O seu endereço de email não será publicado.