2013-04-03 34 views
19
class human(object): 
    def __init__(self, name=''): 
     self.name = name 

    @property 
    def name(self): 
     return self._name 

    @name.setter 
    def name(self, value): 
     self._name = value 

class superhuman(human): 
    @property 
    def name(self): 
     return 'super ' + name 

s = superhuman('john') 
print s.name 

# Doesn't work :("AttributeError: can't set attribute" 
s.name = 'jack' 
print s.name 

Tôi muốn có thể ghi đè thuộc tính nhưng có thể sử dụng trình thiết lập của cha mẹ siêu mà không cần phải ghi đè bộ cài đặt trong lớp con.Giá trị ghi đè của Python không cần thiết lập

Đó có phải là pythonicaly có thể không?

Trả lời

33

Sử dụng chỉ các .getter trang trí của tài sản gốc:

class superhuman(human): 
    @human.name.getter 
    def name(self): 
     return 'super ' + self._name 

Lưu ý rằng bạn phải sử dụng tên đầy đủ để đạt được mô tả tài sản gốc trên lớp cha mẹ.

diễn:

>>> class superhuman(human): 
...  @human.name.getter 
...  def name(self): 
...   return 'super ' + self._name 
... 
>>> s = superhuman('john') 
>>> print s.name 
super john 
>>> s.name = 'jack' 
>>> print s.name 
super jack 

Đối tượng property mô tả là chỉ một đối tượng, mặc dù nó có thể có nhiều phương pháp liên kết với nó (các getter, setter và deleter). Các hàm .getter, .setter.deleter trang trí được cung cấp bởi bộ mô tả hiện tại property trả lại bản sao của bộ mô tả, với một phương thức cụ thể được thay thế.

Vì vậy, trong lớp cơ sở human của bạn những gì xảy ra là lần đầu tiên bạn tạo mô tả với @property trang trí, sau đó thay thế mà mô tả với một trong đó có cả một getter và setter với cú pháp . Điều đó làm việc vì trang trí python thay thế hàm trang trí ban đầu có cùng tên, về cơ bản nó thực hiện name = name.setter(name). Xem How does the @property decorator work? để biết chi tiết về cách hoạt động của tất cả.

Trong lớp con của bạn, bạn chỉ cần sử dụng thủ thuật đó để tạo bản sao mới của bộ mô tả chỉ với bộ nạp thay thế.