2013-05-07 7 views
5

Sto usando la versione Python: 2.7.3.Come funzionano le funzioni magiche e coercizione/magica di Python?

In Python, usiamo i metodi magici __str__ e __unicode__ per definire il comportamento di str e unicode sulle nostre classi personalizzate:

>>> class A(object): 
    def __str__(self): 
    print 'Casting A to str' 
    return u'String' 
    def __unicode__(self): 
    print 'Casting A to unicode' 
    return 'Unicode' 


>>> a = A() 
>>> str(a) 
Casting A to str 
'String' 
>>> unicode(a) 
Casting A to unicode 
u'Unicode' 

Il comportamento suggerisce che il valore restituito da __str__ e __unicode__ è costretto a uno str o unicode a seconda del metodo magico da eseguire.

Tuttavia, se facciamo questo:

>>> class B(object): 
    def __str__(self): 
    print 'Casting B to str' 
    return A() 
    def __unicode__(self): 
    print 'Casting B to unicode' 
    return A() 


>>> b = B() 
>>> str(b) 
Casting B to str 

Traceback (most recent call last): 
    File "<pyshell#47>", line 1, in <module> 
    str(b) 
TypeError: __str__ returned non-string (type A) 
>>> unicode(b) 
Casting B to unicode 

Traceback (most recent call last): 
    File "<pyshell#48>", line 1, in <module> 
    unicode(b) 
TypeError: coercing to Unicode: need string or buffer, A found 

Calling str.mro() e unicode.mro() dice che entrambi sono sottoclassi di basestring. Tuttavia, __unicode__ consente anche il ritorno degli oggetti buffer, che eredita direttamente da object e non eredita da basestring.

Quindi, la mia domanda è, cosa succede in realtà quando str e unicode si chiamano? Quali sono i requisiti del valore di ritorno su __str__ e __unicode__ per l'uso in str e unicode?

+0

Potrebbe essere necessario cercare il codice sorgente per scoprire questo – Eric

risposta

4

Tuttavia, __unicode__ permette anche il ritorno di oggetti buffer che oggetto direttamente e non ereditano da basestring.

Questo non è corretto. unicode() può convertire una stringa o un buffer. È un "miglior tentativo" di convertire l'argomento passato in unicode usando la codifica predefinita (ecco perché dice coercing). Restituirà sempre un oggetto Unicode.

Quindi, la mia domanda è: cosa succede realmente quando str e unicode sono chiamati ? Quali sono i requisiti del valore di ritorno su __str__ e __unicode__ da utilizzare in str e unicode?

__str__ deve restituire una rappresentazione di stringa informale e di facile utilizzo per l'oggetto. Questo è ciò che viene chiamato quando qualcuno usa str() sul tuo oggetto, o quando il tuo oggetto fa parte di una dichiarazione di stampa.

__unicode__ deve sempre restituire un oggetto unicode. Se questo metodo non è definito, viene chiamato __str__ e quindi i risultati vengono convertiti in unicode (passando a unicode()).

Nel secondo esempio, vengono restituiti oggetti non validi, motivo per cui vengono visualizzati i messaggi di errore. Il tuo primo esempio sembra funzionare per __unicode__ a causa di un effetto collaterale, ma non è stato scritto correttamente.

La sezione data model della documentazione è la pena di leggere per ulteriori informazioni e dettagli su questi "metodi magici".

+0

Questo dichiara cosa dovrebbe essere restituito, ma la domanda (almeno la mia intenzione era) è perché non puoi restituire qualcos'altro? –

+0

Questi metodi "magici" hanno un determinato protocollo ad essi associato, motivo per cui si ottengono risultati imprevisti se si restituisce qualcosa di diverso da quello che ci si aspetta perché fanno parte del _data model_ degli oggetti. –

Problemi correlati