Esiste una convenzione python per quando è necessario implementare __str__()
rispetto a __unicode__()
. Ho visto le classi ignorare __unicode__()
più frequentemente di __str__()
ma non sembra coerente. Esistono regole specifiche quando è meglio implementare l'una rispetto all'altra? È necessario/buona pratica implementare entrambi?Python __str__ rispetto a __unicode__
risposta
__str__()
è il vecchio metodo - restituisce i byte. __unicode__()
è il nuovo metodo preferito, che restituisce i caratteri. I nomi sono un po 'confusi, ma in 2.x siamo bloccati con loro per motivi di compatibilità. In generale, si dovrebbe mettere tutta la stringa di formattazione in __unicode__()
, e creare uno stub __str__()
metodo:
def __str__(self):
return unicode(self).encode('utf-8')
In 3.0, str
contiene caratteri, quindi gli stessi metodi sono chiamati __bytes__()
e __str__()
. Questi si comportano come previsto.
Con il mondo sempre più piccolo, è probabile che qualsiasi stringa che incontrerai conterrà infine Unicode. Quindi, per qualsiasi nuova app, dovresti almeno fornire __unicode__()
. Se si sostituisce anche __str__()
è solo una questione di gusti.
Se non mi interessasse particolarmente l'ottimizzazione delle micro-ottimizzazioni per una determinata classe, implementerei sempre __unicode__
, in quanto è più generale. Quando mi preoccupo di problemi di prestazioni così minuti (che è l'eccezione, non la regola), avendo solo __str__
(quando posso provare che non ci saranno mai caratteri non ASCII nell'output con stringhe) o entrambi (quando entrambi sono possibili), potrebbe aiutare.
Questi penso siano solidi principi, ma in pratica è molto comune SAPERE che non ci saranno nient'altro che caratteri ASCII senza fare alcuno sforzo per dimostrarlo (ad es. La forma stringificata ha solo cifre, punteggiatura e forse un breve nome ASCII; -) nel qual caso è abbastanza tipico passare direttamente all'approccio "just __str__
" (ma se un team di programmazione con cui ho lavorato ha proposto una linea guida locale per evitarlo, sarei +1 sulla proposta, poiché è facile err in queste materie E "l'ottimizzazione prematura è la radice di tutto il male nella programmazione" ;-).
in Python 2.6.2, ho recentemente ottenuto sgambetto perché le istanze di una particolare sottoclasse Exception incorporata ha dato risultati diversi con str (e) e unicode (e). str (e) ha dato un output user-friendly; unicode (e) ha dato un output diverso, user-unfriendly. Si considera un comportamento bacato? La classe è UnicodeDecodeError; Non l'ho chiamato in primo piano per evitare confusione - il fatto che l'eccezione sia correlata all'unicode non è particolarmente rilevante. –
Se si sta lavorando sia in python2 e python3 in Django, vi consiglio il decoratore python_2_unicode_compatible:
Django fornisce un modo semplice per definire str() e unicode() metodi che funzionano su Python 2 e 3: è necessario definire un metodo str() per restituire il testo e applicare il decoratore python_2_unicode_compatible().
Come notato nei commenti precedenti a un'altra risposta, alcune versioni di future.utils supportano anche questo decoratore. Sul mio sistema, avevo bisogno di installare un nuovo modulo futuro per python2 e installare future per python3. Dopo di che, quindi ecco un esempio funzionale:
#! /usr/bin/env python
from future.utils import python_2_unicode_compatible
from sys import version_info
@python_2_unicode_compatible
class SomeClass():
def __str__(self):
return "Called __str__"
if __name__ == "__main__":
some_inst = SomeClass()
print(some_inst)
if (version_info > (3,0)):
print("Python 3 does not support unicode()")
else:
print(unicode(some_inst))
Ecco esempio di uscita (dove venv2/venv3 sono casi virtualenv):
~/tmp$ ./venv3/bin/python3 demo_python_2_unicode_compatible.py
Called __str__
Python 3 does not support unicode()
~/tmp$ ./venv2/bin/python2 demo_python_2_unicode_compatible.py
Called __str__
Called __str__
sa che intendi creare entrambi i metodi __unicode__ e __str__ o semplicemente mantenere le stringhe in _ (u "") e creare __string__ (senza il metodo unicode)? – muntu
C'è qualche trappola nell'implementazione di uno solo di essi? Cosa succede quando implementate solo "__unicode__" e poi "str (obj)"? – RickyA
'unicode' solleva un' NameError' su Python 3, è un pattern semplice che funziona sia su 2 che su 3? –