2016-04-29 9 views
1

Wie die offizielle Demo beschrieben here, wird der folgende Code Retrieving var "x" drucken.Python-Datendeskriptor funktionierte nicht als Instanzvariable?

class RevealAccess(object): 
    """A data descriptor that sets and returns values 
     normally and prints a message logging their access. 
    """ 

    def __init__(self, initval=None, name='var'): 
     self.val = initval 
     self.name = name 

    def __get__(self, obj, objtype): 
     print 'Retrieving', self.name 
     return self.val 

    def __set__(self, obj, val): 
     print 'Updating', self.name 
     self.val = val 


class MyClass1(object): 
    x = RevealAccess(10, 'var "x"') 

MyClass1().x 

Aber wenn x eine Instanzvariable ist, werden die Daten Descriptor Maschinen nicht funktionieren, wird der folgende Code nicht alles drucken.

class MyClass2(object): 
    def __init__(self): 
     self.x = RevealAccess(10, 'var "x"') 

MyClass2().x 

Und wenn ich implementiert manuell die Daten Descriptor Maschinen wie here beschrieben, wird der folgende Code Retrieving var "x" wieder.

class MyClass3(object): 
    def __init__(self): 
     self.x = RevealAccess(10, 'var "x"') 

    def __getattribute__(self, key): 
     "Emulate type_getattro() in Objects/typeobject.c" 
     v = object.__getattribute__(self, key) 
     if hasattr(v, '__get__'): 
      return v.__get__(None, self) 
     return v 

MyClass3().x 

Also, ist der Standard-Datendeskriptor Maschinerie nicht implementiert, wie das Dokument beschrieben?

Ich benutze Python 2.7.10.

Antwort

3

Der Deskriptor How-To ist hier falsch. Die Python data model hat die richtige Beschreibung:

die folgenden Methoden [__get__, __set__ und __delete__] nur dann Anwendung, wenn eine Instanz der Klasse das Verfahren enthält (eine sogenannte Deskriptor Klasse) erscheint in einer Eigentümer Klasse (Der Deskriptor muss entweder in der Klasse des Besitzers oder im Klassenwörterbuch für einen seiner Eltern sein).

Deskriptoren müssen Klassenattribute sein.

Verwandte Themen