2014-04-26 15 views
8

Quando eseguo la variabile "data" come variabile di classe, il seguente funziona, ma quando lo faccio una variabile oggetto, il descrittore non viene chiamato. Per favore aiuto.Perché il descrittore non viene chiamato quando definito come attributo di istanza?

class Data(object): 
    products = { 
     'milk': {'price': 1.50, 'quantity': 10}, 
     'eggs': {'price': 0.20, 'quantity': 100}, 
     'cheese': {'price': 2.00, 'quantity': 10} 
    } 
    def __get__(self, obj, klas): 
     print "Here in descriptor" 
     return self.products 

class BusinessLogic(object): 
    def __init__(self):   # When I remove these 2 lines 
     self.data = Data() 
    #data = Data()    # and enable this line it does work ! 

def main(): 
    b = BusinessLogic() 
    b.data 

if __name__ == '__main__': 
    main() 

risposta

12

Questo perché descrittori dovrebbero essere definiti solo come attributi di classe, non esempio attributi:

Da docs:

I seguenti metodi applicano solo quando un'istanza della classe contenente il metodo (una cosiddetta classe descrittore) appare in una classe di proprietario (il descrittore deve essere nel dizionario della classe del proprietario o nella classe di ctionary per uno dei suoi genitori). .

per rendere il lavoro descrittore di esempio attributi così è necessario eseguire l'override del metodo di BusinessLogic__getattribute__ (non ho ancora testato questo fondo, ma funziona bene per il vostro caso):

def __getattribute__(self, attr): 
     obj = object.__getattribute__(self, attr) 
     if hasattr(obj, '__get__'): 
      return obj.__get__(self, type(self)) 
     return obj 

Nel caso in cui hai un descrittore di dati quindi devi gestire anche la parte __setattr__.

def __setattr__(self, attr, val): 
    try: 
     obj = object.__getattribute__(self, attr) 
    except AttributeError: 
     # This will be raised if we are setting the attribute for the first time 
     # i.e inside `__init__` in your case. 
     object.__setattr__(self, attr, val) 
    else: 
     if hasattr(obj, '__set__'): 
      obj.__set__(self, val) 
     else: 
      object.__setattr__(self, attr, val) 
+0

Capito, grazie! – Arovit

+0

@Aro Verifica anche la risposta aggiornata. :) –

+0

Questo è fantastico! Grazie per questa risposta, mi ha davvero aiutato. – SeedyROM

Problemi correlati