2009-01-09 5 views
2

Pour illustrer la question vérifier le code suivant:Pourquoi les attributs gérés fonctionnent-ils uniquement pour les attributs de classe et non pas par exemple les attributs dans python?

class MyDescriptor(object): 
    def __get__(self, obj, type=None): 
    print "get", self, obj, type 
    return self._v 
    def __set__(self, obj, value): 
    self._v = value 
    print "set", self, obj, value 
    return None 

class SomeClass1(object): 
    m = MyDescriptor() 

class SomeClass2(object): 
    def __init__(self): 
    self.m = MyDescriptor() 

x1 = SomeClass1() 
x2 = SomeClass2() 

x1.m = 1000 
# -> set <__main__.MyDescriptor object at 0xb787c7ec> <__main__.SomeClass1 object at 0xb787cc8c> 10000 
x2.m = 1000 # I guess that this overwrites the function. But why? 
# -> 
print x1.m 
# -> get <__main__.MyDescriptor object at 0xb787c7ec> <__main__.SomeClass1 object at 0xb787cc8c> <class '__main__.SomeClass1'> 10000 
print x2.m 
# -> 10000 
  1. Pourquoi ne pas x2.m = 1000 pas appeler la __set__ -fonction? Il semble que cela écrase la fonction. Mais pourquoi?
  2. Où est _v dans x1? Il n'est pas x1._v

Répondre

3

Pour répondre à votre deuxième question, où est _v? La version du descripteur conserve _v dans le descripteur lui-même. Chaque instance du descripteur (le niveau de l'instance de classe SomeClass1, et toutes les instances de niveau d'objet dans les objets de la classe SomeClass2 aura des valeurs distinctes de _v.

Regardez cette version. Cette version met à jour l'objet associé à la descripteur. Cela signifie que l'objet (ou SomeClass1x2) contiendra l'attribut _v.

class MyDescriptor(object): 
    def __get__(self, obj, type=None): 
    print "get", self, obj, type 
    return obj._v 
    def __set__(self, obj, value): 
    obj._v = value 
    print "set", self, obj, value 
+0

Merci, c'est une bonne idée à mettre en œuvre. Une question à _v: Je ne pouvais pas non plus y accéder via "MyDescriptor._v" - ce qui est clair car ce n'est pas un attribut de classe de MyDescriptor. Mais quel est le nom explicite de l'instance? Il devrait être accessible d'une façon ou d'une autre, n'est-ce pas? –

+0

Vous ne pouvez pas y accéder, car il est écrasé. Dans le cas S.Lott, vous pouvez y accéder via x._v – Seb

+0

ehh, désolé, x1._v – Seb

3

Vous devriez lire this et this.

Il overwri teste la fonction car vous n'avez pas surchargé les fonctions __set__ et __get__ de SomeClass mais de la classe MyDescriptor. Peut-être vouliez-vous que SomeClass hérite de MyDescriptor? SomeClass1 imprime la sortie "get" et "set" parce que c'est une méthode statique AFAIK. Pour plus de détails, lisez les liens supérieurs.

0

Je trouve _v de x1: Il est SomeClass1 .__ dict __ [ 'm'] ._ v

Pour la version proposée par S. Lott dans l'autre réponse: _v est dans x1._v

Questions connexes