Existe uma convenção python para quando você deve implementar __str__()
versus __unicode__()
. Vi classes substituir com __unicode__()
mais frequência do que __str__()
mas não parece ser consistente. Existem regras específicas quando é melhor implementar uma versus a outra? É necessário / boa prática implementar ambos?
fonte
__unicode__
e depois fazstr(obj)
?unicode
gera umNameError
no Python 3, é um padrão simples que funciona tanto no 2 quanto no 3?future
pacote também fornecepython_2_unicode_compatible
sem ter o Django como uma dependência.Se eu não me importasse especialmente com a otimização de micro-otimização para uma determinada classe, eu sempre implementaria
__unicode__
apenas, pois é mais geral. Quando eu me importo com esses problemas de desempenho minuciosos (que é a exceção, não a regra), ter__str__
apenas (quando eu puder provar que nunca haverá caracteres não-ASCII na saída com string) ou ambos (quando ambos forem possíveis), poderá Socorro.Eu acho que são princípios sólidos, mas, na prática, é muito comum SABER que não haverá nada além de caracteres ASCII sem fazer esforço para provar isso (por exemplo, a forma estrita tem apenas dígitos, pontuação e talvez um nome ASCII curto ;-) no qual caso seja bastante comum seguir diretamente para a
__str__
abordagem " justa " (mas se uma equipe de programação com a qual trabalhei propusesse uma diretriz local para evitar isso, eu seria +1 na proposta, pois é fácil errar nessas questões) "otimização prematura é a raiz de todo mal na programação" ;-).fonte
Com o mundo cada vez menor, é provável que qualquer sequência que você encontre conterá Unicode eventualmente. Portanto, para qualquer novo aplicativo, você deve pelo menos fornecer
__unicode__()
. Se você também substitui__str__()
é apenas uma questão de gosto.fonte
Se você estiver trabalhando em python2 e python3 no Django, recomendo o decorador python_2_unicode_compatible:
Como observado nos comentários anteriores de outra resposta, algumas versões do future.utils também suportam esse decorador. No meu sistema, eu precisava instalar um módulo futuro mais recente para python2 e instalar o futuro para python3. Depois disso, aqui está um exemplo funcional:
Aqui está um exemplo de saída (em que venv2 / venv3 são instâncias virtualenv):
fonte
Python 2: implemente apenas __str __ () e retorne um unicode.
Quando
__unicode__()
é omitido e alguém chamaunicode(o)
ouu"%s"%o
, Python chamao.__str__()
e converte em unicode usando a codificação do sistema. (Veja a documentação de__unicode__()
.)O oposto não é verdadeiro. Se você implementar,
__unicode__()
mas não__str__()
, quando alguém chamarstr(o)
ou"%s"%o
, o Python retornarárepr(o)
.Fundamentação
Por que isso funciona para retornar a
unicode
partir de__str__()
?Se
__str__()
retornar um unicode, o Python o converterá automaticamentestr
usando a codificação do sistema.Qual o benefício?
① Isso evita que você se preocupe com o que é a codificação do sistema (ou seja,
locale.getpreferredencoeding(…)
). Não é apenas isso confuso, pessoalmente, mas acho que é algo que o sistema deve resolver de qualquer maneira. ② Se você for cuidadoso, seu código pode ser compatível com o Python 3, no qual__str__()
retorna unicode.Não é enganoso retornar um unicode de uma função chamada
__str__()
?Um pouco. No entanto, você já pode estar fazendo isso. Se você estiver
from __future__ import unicode_literals
na parte superior do arquivo, há uma boa chance de retornar um unicode sem nem mesmo saber.E o Python 3?
Python 3 não usa
__unicode__()
. No entanto, se você implementar__str__()
para que ele retorne unicode no Python 2 ou Python 3, essa parte do seu código será compatível com outras versões.E se eu quiser
unicode(o)
ser substancialmente diferentestr()
?Implemente ambos
__str__()
(possivelmente retornandostr
) e__unicode__()
. Eu imagino que isso seria raro, mas você pode querer uma saída substancialmente diferente (por exemplo, versões ASCII de caracteres especiais, como":)"
parau"☺"
).Sei que alguns podem achar isso controverso.
fonte
Vale ressaltar para aqueles que não estão familiarizados com a
__unicode__
função alguns dos comportamentos padrão que a envolvem no Python 2.x, especialmente quando definidos lado a lado__str__
.produz a seguinte saída do console ...
Agora, quando eu descomente o
__str__
métodofonte