2013-05-18 68 views
0

我有以下兩類:通知有關的屬性更改父實例

class Status(object): 
    def __init__(self): 
     self._message = '' 

    @property 
    def message(self): 
     return self._message 

    @message.setter 
    def message(self, value): 
     self._message = value 


class Buddy(object): 
    def __init__(self, name): 
     self.name = name 
     self.status = Status() 

    def status_updated(self): 
     # this should be called when self.status.message is changed 

和我使用它們像這樣:

buddy = Buddy('John') 
buddy.status.message = 'Hello world!' # this should call Buddy.status_updated 

我想Buddy.status_updated被稱爲當我修改Statusmessage財產。如何實現這一目標?

回答

3

您必須將參考返回存儲到父級;蟒蛇值不跟蹤它們的存儲位置(有可能是指你的Status()情況下,多個地方):

class Status(object): 
    def __init__(self, parent=None): 
     self._message = '' 
     self._parent = parent 

    @property 
    def message(self): 
     return self._message 

    @message.setter 
    def message(self, value): 
     self._message = value 
     if self._parent is not None: 
      self._parent.status_updated() 


class Buddy(object): 
    def __init__(self, name): 
     self.name = name 
     self.status = Status(self) 

    def status_updated(self): 
     # this should be called when self.status.message is changed 
+0

我很害怕,這將是答案。謝謝! – ov1d1u

+0

另一種方法是使用某種事件系統(訂閱者,事件發佈者等)。 –

1

在你需要以某種方式註冊要「聽」到其他的對象屬性更改每一種情況下。我建議簡單的解決辦法是這樣的:

class Status(object): 
    def __init__(self, on_message_change=None): 
     self._message, self._on_message_change = '', on_message_change 

    @property 
    def message(self): 
     return self._message 

    @message.setter 
    def message(self, value): 
     if self._on_message_change: 
      self._on_message_change(self._message, value) 
     self._message = value 


class Buddy(object): 
    def __init__(self, name): 
     self.name = name 
     self.status = Status(self.status_updated) 

    def status_updated(self, old_value, new_value): 
     print("status changed '%s' -> '%s'" % (old_value, new_value)) 

b = Buddy("someone") 
b.status.message = "init" 
b.status.message = "new" 

輸出爲:

status changed '' -> 'init' 
status changed 'init' -> 'new'