2012-02-06 48 views
8

Tôi là một chút nhầm lẫn về tài sản trong python. Xét đoạn mã saupython tài sản getter/setter nhầm lẫn

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 nên một cái gì đó giống như một wrapper cho A. Nó sử dụng getter và setter để ánh xạ các thuộc tính của một trên chính nó (tất nhiên người ta cũng có thể làm điều đó thông qua thừa kế). Vấn đề là, rằng nó chỉ đơn giản không hoạt động như mong đợi trong python2.6 trong khi nó ở 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 

Tôi có làm điều gì sai trái hoặc nơi chính xác là vấn đề?

Trả lời

18

A và B phải là các lớp kiểu mới trong Python 2.x.

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

Return một thuộc tính tài sản cho new-style classes (lớp dẫn xuất từ ​​object).

Vì vậy, nếu bạn sẽ lấy được từ object

class A(object): 
    ... 

class B(object): 
    ... 

Mã của bạn sẽ làm việc như mong đợi.

+0

ok bạn nói đúng, giải quyết nó nhưng tôi vẫn không hiểu điều gì sai ở đây. – buergi

+1

@buergi Các lớp kiểu cũ không thể có phần mô tả. '@ property' là bộ mô tả. Thông tin thêm tại [Tham khảo mô hình dữ liệu Python] (http://docs.python.org/reference/datamodel.html) – reclosedev