通知父实例有关属性更改

时间:2013-05-18 16:08:07

标签: python class oop properties setter

我有这两个类:

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的{​​{1}}属性时调用message。怎么做到这一点?

2 个答案:

答案 0 :(得分:3)

您必须将参考保存回给父母; python值不会跟踪它们的存储位置(可能有多个地方引用您的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

答案 1 :(得分: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'