As muitas maneiras de formatação de strings do Python - as mais antigas (serão) obsoletas?

106

Python tem pelo menos seis maneiras de formatar uma string:

In [1]: world = "Earth"

# method 1a
In [2]: "Hello, %s" % world
Out[2]: 'Hello, Earth'

# method 1b
In [3]: "Hello, %(planet)s" % {"planet": world}
Out[3]: 'Hello, Earth'

# method 2a
In [4]: "Hello, {0}".format(world)
Out[4]: 'Hello, Earth'

# method 2b
In [5]: "Hello, {planet}".format(planet=world)
Out[5]: 'Hello, Earth'

# method 2c
In [6]: f"Hello, {world}"
Out[6]: 'Hello, Earth'

In [7]: from string import Template

# method 3
In [8]: Template("Hello, $planet").substitute(planet=world)
Out[8]: 'Hello, Earth'

Uma breve história dos diferentes métodos:

  • printfa formatação de estilo existe desde a infância de Pythons
  • A Templateclasse foi introduzida em Python 2.4
  • O formatmétodo foi introduzido no Python 2.6
  • f-strings foram introduzidos no Python 3.6

Minhas perguntas são:

  • A printfformatação -style está obsoleta ou será obsoleta?
  • No Template class, o substitutemétodo foi descontinuado ou será descontinuado? (Não estou falando sobre o safe_substituteque, pelo que entendi, oferece recursos únicos)

Perguntas semelhantes e por que acho que não são duplicatas:

Veja também

gerrit
fonte
1
Preciso apontar que você esqueceu a Formatteraula?
Martijn Pieters

Respostas:

14

Embora existam várias indicações nos documentos de que .formatas strings f são superiores às %strings, não há nenhum plano remanescente para substituir o último.

No commit Problema nº 14123: Mencione explicitamente que a formatação de string% no estilo antigo tem ressalvas, mas não irá desaparecer tão cedo. , inspirado pelo problema Indica que não há planos atuais para descontinuar a formatação do estilo printf , os documentos sobre %formatação foram editados para conter esta frase:

Como a nova sintaxe de formatação de strings é mais flexível e lida com tuplas e dicionários naturalmente, ela é recomendada para novos códigos. No entanto, não há planos atuais para descontinuar a formatação do estilo printf .

(Ênfase minha.)

Esta frase foi removida posteriormente, no commit Close # 4966: renovar a documentação da sequência para explicar melhor o estado do Python moderno . Isso pode parecer um sinal de que um plano para descontinuar a %formatação estava de volta aos cartões ... mas mergulhar no rastreador de bug revela que a intenção era oposta. No rastreador de bug, o autor do commit caracteriza a mudança assim :

  • mudou a prosa que descreve a relação entre a formatação no estilo printf e o método str.format (removendo deliberadamente a implicação de que o primeiro representa qualquer perigo real de desaparecer - simplesmente não é prático para nós pensarmos seriamente em matá-lo)

Em outras palavras, tivemos duas alterações consecutivas nos %documentos -formatting com a intenção de enfatizar explicitamente que não será descontinuado, muito menos removido. Os documentos permanecem opinativos sobre os méritos relativos de diferentes tipos de formatação de string, mas também estão claros que a %-formatação não será descontinuada ou removida.

Além do mais, a alteração mais recente nesse parágrafo , em março de 2017, mudou deste ...

As operações de formatação descritas aqui exibem uma variedade de peculiaridades que levam a uma série de erros comuns (como não exibir tuplas e dicionários corretamente). Usar os literais de string formatados mais recentes ou a str.formatinterface ajuda a evitar esses erros. Essas alternativas também fornecem abordagens mais poderosas, flexíveis e extensíveis para a formatação de texto.

... para isso:

As operações de formatação descritas aqui exibem uma variedade de peculiaridades que levam a uma série de erros comuns (como não exibir tuplas e dicionários corretamente). Usar os literais de string formatados mais recentes, a str.formatinterface ou as strings de modelo podem ajudar a evitar esses erros. Cada uma dessas alternativas oferece suas próprias vantagens e desvantagens de simplicidade, flexibilidade e / ou extensibilidade.

Observe a mudança de "ajuda a evitar" para "pode ​​ajudar a evitar", e como a recomendação clara de .formatcordas-F foi substituída por uma prosa fofa e equívoca sobre como cada estilo "fornece suas próprias compensações e benefícios" . Ou seja, não apenas uma reprovação formal não está mais nos cartões, mas os documentos atuais estão reconhecendo abertamente que a %formatação tem pelo menos alguns "benefícios" em relação às outras abordagens.

Eu deduzo de tudo isso que o movimento para descontinuar ou remover a %formatação não apenas vacilou, mas foi derrotado completa e permanentemente.

Mark Amery
fonte
2
A mudança de linguagem fofa foi adicionada para aplacar os mantenedores do Mercurial (entre outros) que não queriam ver o Mercurial deixado para trás com uma base de código muito grande para erradicar o uso %. Agora que a política de "não usar mods de código em grande escala" foi descartada, suas objeções também estão desaparecendo. No longo prazo, a manutenção de ambos os formulários sem nenhum benefício restante, pois % em algum ponto a sintaxe do printf será removida de qualquer maneira. Só não sabemos quando ainda, então valia a pena diminuir o tom da linguagem.
Martijn Pieters
@MartijnPieters Interesting. Parece que você tem um grande conhecimento sobre essa decisão que me falta. Pelo que vale a pena, acho que uma resposta bem referenciada de você delineando esses pontos (como uma nova resposta ou uma edição da existente) teria valor.
Mark Amery de
58

O novo .format()método pretende substituir a %sintaxe de formatação antiga . O último foi enfatizado, (mas não oficialmente obsoleto ainda ). A documentação do método afirma tanto:

Este método de formatação de string é o novo padrão no Python 3 e deve ser preferido à %formatação descrita em Operações de formatação de string em novo código.

(Ênfase minha).

Para manter a compatibilidade com versões anteriores e tornar a transição mais fácil, o formato antigo foi deixado no lugar por enquanto . Da proposta PEP 3101 original :

Compatibilidade com versões anteriores

A compatibilidade com versões anteriores pode ser mantida, deixando os mecanismos existentes no lugar. O novo sistema não colide com nenhum dos nomes de método das técnicas de formatação de string existentes, portanto, os dois sistemas podem coexistir até chegar a hora de descontinuar o sistema anterior.

Observe que até chegar a hora de descontinuar o sistema antigo ; ele não se tornou obsoleto, mas o novo sistema deve ser usado sempre que você escrever um novo código .

O novo sistema tem a vantagem de poder combinar a abordagem de tupla e dicionário do %formatador antigo :

"{greeting}, {0}".format(world, greeting='Hello')

e é extensível por meio do object.__format__()gancho usado para manipular a formatação de valores individuais.

Observe que o antigo sistema possuía %e a Templateclasse, onde a última permite criar subclasses que adicionam ou alteram seu comportamento. O sistema de novo estilo tem Formatterclasse para preencher o mesmo nicho.

Python 3 ainda reforçou longe de depreciação, em vez dando-lhe aviso na printfstring de formatação de estilo seção :

Nota : As operações de formatação descritas aqui exibem uma variedade de peculiaridades que levam a uma série de erros comuns (como não exibir tuplas e dicionários corretamente). Usar os literais de string formatados mais recentes ou a str.format()interface ajuda a evitar esses erros. Essas alternativas também fornecem abordagens mais poderosas, flexíveis e extensíveis para a formatação de texto.

O Python 3.6 também adicionou literais de string formatadas , que alinham as expressões nas strings de formato. Esses são o método mais rápido de criar strings com valores interpolados e devem ser usados ​​em vez de str.format()onde você puder usar um literal.

Martijn Pieters
fonte
4
E com Formattervocê pode criar formatos personalizados, como aqueles que os datetimeobjetos usam. Além disso, como .formaté uma função, você pode usá-la para criar uma formatação lenta que pode ser chamada mais diretamente: por exemplo,fmt = '{} - {}'.format; fmt(a, b)
Jon Clements
Não vejo como Templatese relaciona com %ou com o sistema antigo . Em particular, o PEP que você vincula estados Embora haja alguma sobreposição entre esta proposta e string.Template, parece que cada uma atende a uma necessidade distinta e que uma não elimina a outra. Em sua resposta, pode ficar confuso que a Templateformatação, por fazer parte do sistema antigo , também está obsoleta.
Bakuriu
@Bakuriu: Certo, acho que perdi essa parte; mas na minha opinião a Formatterclasse pode preencher as mesmas necessidades que string.Template().
Martijn Pieters
1
[...]should be preferred to the % formatting[...]esta parte foi removida da documentação. docs.python.org/3/library/stdtypes.html#str.format
AXO
Acho que essa resposta atualmente é enganosa; a primeira passagem citada foi removida da documentação do Python 3, e parece bastante claro para mim que não há nenhuma intenção restante para que ocorra uma depreciação. Essa resposta ainda tem valor histórico, mas estou inclinado a ajustar o texto para evitar qualquer sugestão de que uma depreciação ainda está nos cartões e editar grande parte da primeira metade da resposta para estar no pretérito. Eu mesmo farei isso em algum momento se você não se opor, mas pensei em comentar primeiro para dar a você a chance de fazer essas mudanças sozinho, se desejar.
Mark Amery de
45

O %operador para formatação de string não é obsoleto e não será removido - apesar das outras respostas.
Cada vez que o assunto é levantado na lista de desenvolvimento do Python, há uma forte controvérsia sobre qual é o melhor, mas nenhuma controvérsia sobre se remover a forma clássica - ela permanecerá. Apesar de ser indicado no PEP 3101, o Python 3.1 veio e se foi, e a %formatação ainda está por aí.

As afirmações para manter o estilo clássico são claras: é simples, é rápido, é rápido para fazer coisas curtas. Usar o .formatmétodo nem sempre é mais legível - e quase ninguém - mesmo entre os desenvolvedores principais, pode usar a sintaxe completa fornecida por .formatsem ter que olhar para a referência Mesmo em 2009, havia mensagens como esta: http: // mail. python.org/pipermail/python-dev/2009-October/092529.html - o assunto quase não apareceu nas listas desde então.

Atualização de 2016

Na versão atual de desenvolvimento do Python (que se tornará o Python 3.6), há um terceiro método de interpolação de string, descrito no PEP-0498 . Ele define um novo prefixo de citação f""(além do atual u"", b""e r"").

Prefixar uma string por fchamará um método no objeto string no tempo de execução, que interpola automaticamente as variáveis ​​do escopo atual na string:

>>> value = 80
>>> f'The value is {value}.'
'The value is 80.'
jsbueno
fonte
3
É muito mais agradável permitir que os tipos implementem seus próprios __format__. Por exemplo, format(Decimal('0.1'), '.20f')vs '%.20f' % Decimal('0.1'). O último transforma o decimal em ponto flutuante.
Eryk Sun
2
NB. Não argumentei que o estilo antigo é melhor em todos os aspectos - apenas que é mais curto e às vezes mais legível (às vezes não). Certamente, a nova forma é muito mais flexível.
jsbueno
Existe um equivalente para fem Python 3?
Daniel de
Os f-stringsusados ​​acima são novos recursos na linguagem a partir do Python 3.6. Ele não existe nas versões anteriores e gerará um erro de sintaxe nelas.
jsbueno de
20

A última posição de Guido sobre isso parece estar indicada aqui:

O que há de novo no Python 3.0

PEP 3101: Uma nova abordagem para formatação de strings

Um novo sistema para operações de formatação de string incorporadas substitui o operador de formatação de string%. (No entanto, o operador% ainda é compatível; ele será descontinuado no Python 3.1 e removido da linguagem posteriormente.) Leia o PEP 3101 para obter informações completas.

E o próprio PEP3101 , que tem a última modificação datada de (Sex, 30 de setembro de 2011), então nenhum progresso até agora, eu suponho.

GSP
fonte
18

Olhando para os documentos Python mais antigos e o PEP 3101, havia uma declaração de que o operador% será descontinuado e removido da linguagem no futuro. A declaração a seguir estava na documentação do Python para Python 3.0, 3.1 e 3.2:

Como str.format () é bastante novo, muito código Python ainda usa o operador%. No entanto, como esse estilo antigo de formatação será eventualmente removido da linguagem, str.format () geralmente deve ser usado.

Se você for para a mesma seção nos documentos do Python 3.3 e 3.4, verá que a instrução foi removida. Também não consigo encontrar qualquer outra declaração em qualquer outro lugar na documentação indicando que o operador será descontinuado ou removido do idioma. Também é importante observar que o PEP3101 não é modificado há mais de dois anos e meio (sexta-feira, 30 de setembro de 2011).

Atualizar

PEP461 Adicionar% formatação a bytes e bytearray é aceito e deve fazer parte do Python 3.5 ou 3.6. É outro sinal de que o operador% está vivo e ativo.

Marwan Alsabbagh
fonte