2012-02-06 31 views
8

Sono un po 'confuso riguardo le proprietà in python. Si consideri il seguente codiceproprietà python getter/setter confusione

class A: 
    @property 
    def N(self): 
     print("A getter") 
     return self._N 
    @N.setter 
    def N(self,v): 
     print("A setter") 
     self._N = v 

    def __init__(self): 
     self._N = 1 

class B: 
    @property 
    def N(self): 
     print("B getter") 
     return self.a.N 
    @N.setter 
    def N(self,v): 
     print("B setter") 
     self.a.N = v 

    def __init__(self): 
     self.a = A() 

if __name__ == '__main__': 
    b=B() 
    b.N = 2 
    print(b.N, b.a.N) 
    b.N = 3 
    print(b.N, b.a.N) 

B dovrebbe essere qualcosa di simile a un wrapper per A. Esso utilizza getter e setter per mappare le proprietà di un su se stesso (naturalmente si potrebbe anche farlo tramite l'ereditarietà). Il problema è, che semplicemente non funziona come previsto in python2.6 mentre lo fa in python3:

> python2 test.py 
A getter 
(2, 1) 
A getter 
(3, 1) 

> python3 test.py 
B setter 
A setter 
B getter 
A getter 
A getter 
2 2 
B setter 
A setter 
B getter 
A getter 
A getter 
3 3 

Sto facendo qualcosa di sbagliato o dove esattamente è il problema?

risposta

18

A e B devono essere classi di nuovo stile in Python 2.x.

property([fget[, fset[, fdel[, doc]]]])

ritorno un attributo di proprietà per new-style classes (classi che derivano da object).

Quindi, se ti derivano da object

class A(object): 
    ... 

class B(object): 
    ... 

Il codice funzionerà come previsto.

+0

ok hai ragione, questo lo risolve ma non capisco comunque cosa va storto qui. – buergi

+1

@buergi Le classi vecchio stile non possono avere descrittori. '@ property' è descrittore. Maggiori informazioni su [Python Data model reference] (http://docs.python.org/reference/datamodel.html) – reclosedev