2012-06-12 21 views
5

Dieser Code erzeugt einen anderen Ausgang in Python 2 und Python 3.Python-Deskriptoren funktionieren nicht 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') 

Die Ausgabe für Python 2:

read 
read 
finished 

Für Python 3 ist:

read 
write 
del 
read 
finished 

Warum ist dies so zu arbeiten? Wie unterscheiden sich Python 2 Deskriptoren von Deskriptoren?

Dies auch keinen Sinn macht, weil http://docs.python.org/release/3.0.1/reference/datamodel.html#invoking-descriptors eindeutig genau das gleiche beschreibt wie http://docs.python.org/reference/datamodel.html#invoking-descriptors

(Dies sind die Dokumentationen für Python 2.7 und Python 3.0.)

+0

(BTW, Python 3.0 und deren Dokumentation sind veraltet und im Ruhestand, haben Python nicht 3.0 oder 3.0.1 verwenden Die aktuellen Dokumente sind unter http:. // docs. Python.org/py3k/ und die aktuelle Version ist 3.2.3.) –

Antwort

5

Edit: Wie Ned Deily weist genau in den Kommentaren aus Die Grund Dies geschieht, ist Ihre Klasse C ist eine Old-Style-Klasse auf Python 2, da Sie keine object oder eine andere New-Style-Klasse als Basisklasse angegeben haben.


Weil auf Python 2, sind Sie Erstellen einer neuen Instanz Attribut c.a wenn Sie c.a = 3 tun, die den Deskriptor Objekt in C.a befindet sich versteckt.

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

gibt:

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

Aber das würde bedeuten, ich könnte __set__ Deskriptoren in Python 2 nicht verwenden. Und warum ist das in Python 3 anders? –

+9

Ihre Klasse C ist eine alte Klasse in Python 2. Ändern Sie sie in 'Klasse C (Objekt)' und Py 2 funktioniert genauso wie Py 3. –

+0

verdammt! Entschuldigung, dass du diese Frage auch geschrieben hast. :-) Ich habe 'Descriptor' in eine neue Stilklasse geändert, habe aber nicht gesehen, dass' C' keine neue Stilklasse ist. Danke Ned. –