2012-06-12 12 views
5

Questo codice produce un'uscita diversa in Python 2 e Python 3.I descrittori Python non funzionano in Python 2.7

class Descriptor(object): 
    def __get__(self, instance, owner): 
     print('read') 
     return 1 

    def __set__(self, instance, value): 
     print('write') 

    def __delete__(self, instance): 
     print('del') 

class C(): 
    a = Descriptor() 

c = C()         
c.a          
c.a = 3 
del c.a 
c.a 

print('finished') 

L'uscita per Python 2 è:

read 
read 
finished 

Per Python 3 è:

read 
write 
del 
read 
finished 

Perché questo funziona in questo modo? In che modo i descrittori Python 2 sono diversi dai descrittori Python 3?

Questo rende anche non ha senso, perché http://docs.python.org/release/3.0.1/reference/datamodel.html#invoking-descriptors descrive chiaramente esattamente lo stesso di http://docs.python.org/reference/datamodel.html#invoking-descriptors

(Queste sono le documentazioni per Python 2.7 e Python 3.0.)

+0

(BTW, Python 3.0 e la relativa documentazione sono obsolete e in pensione, non utilizzare Python 3.0 o 3.0.1 La documentazione attuali sono a http: //. Docs. python.org/py3k/ e la versione corrente è 3.2.3.) –

risposta

5

Edit: Come Ned deily sottolinea con precisione nei commenti , il motivo questo succede è la tua classe C è una classe vecchio stile su Python 2, poiché non hai specificato object o un'altra classe di nuovo stile come sua classe base.


Perché su Python 2, si sta creando una nuova istanza attributo c.a quando fate c.a = 3 che nasconde l'oggetto descrittore situato a C.a.

c = C() 
c.a 
c.a = 3 
print c.__dict__['a'] 
print C.__dict__['a'] 
del c.a 
c.a 

dà:

read 
3 
<__main__.Descriptor object at 0x04625570> 
read 
finished 
+1

Ma questo significherebbe, non potrei usare i descrittori __set__ in python 2. E perché questo è diverso in Python 3? –

+9

La tua classe C è una classe vecchio stile in Python 2. Passa a 'Classe C (oggetto)' e Py 2 funziona come Py 3. –

+0

dannazione! scusa anche per aver postato questa domanda. :-) Ho cambiato 'Descriptor' in una nuova classe di stile, ma non ho visto che' C' non è una nuova classe di stile. Grazie Ned. –