Python: 多个对象如何修改单个“主”对象的属性

1 投票
2 回答
897 浏览
提问于 2025-04-17 15:53

假设我有一个叫做 master 的对象,它里面包含了一些参数,然后还有多个叫做 slave 的对象,这些 slave 对象需要能够访问和修改 master 的属性。在我的例子中,这些 slave 对象是 wxPython 的图形界面(GUI)控件,可能有多个控件可以修改同一个参数。

如果 slave 想要更新参数,我当然可以直接写 master.parameter,这样很简单。但是我其实不太想这样做,因为这样我就得为每个 slave 对象写不同的函数来处理事件。

目前我做的方式是,master 对象为每个属性都有单独的 get_valueset_value 方法:

class Master(object):
    def __init__(self):
        self.value = 0

    def get_value(self):
        return self.value

    def set_value(self,value):
        self.value = value

class Slave(object):
    def __init__(self,getfunc,setfunc):
        self.getfunc = getfunc
        self.setfunc = setfunc

    def update(self,value):
        self.setfunc(value)

def run():
    master = Master()
    slave = Slave(master.get_value,master.set_value)

    print "\nMaster: %i\nSlave: %i" %(master.value,slave.getfunc())

    slave.update(1)
    print "\nMaster: %i\nSlave: %i" %(master.value,slave.getfunc())

if __name__ == "__main__":
    run()

我真正想要的是能够设置类似 slave.bound_value 的东西,这样它就像是指向 master.value 的一个指针。当任何一个 slave 修改它的 bound_value 时,master 的相应属性也会被更新。我知道 Python 不支持指针,但我在想有没有什么好的 Python 方法可以实现同样的效果呢?

2 个回答

1

感谢bogatron给我指明了方向 - 最后我选择了这个:

class Master(object):
    value = 0

class Slave(object):
    def __init__(self,master,attrname):
        self._master = master
        self._attrname = attrname
    @property
    def value(self):
        return self._master.__getattribute__(self._attrname)
    @value.setter
    def value(self,newvalue):
        self._master.__setattr__(self._attrname,newvalue)

def run():
    master = Master()
    slave = Slave(master,'value')

    print master.value,slave.value
    slave.value = 2
    print master.value,slave.value

if __name__ == "__main__":
    run()
2

你可以通过把 bound_value 变成一个 属性 来实现你想要的效果,这个属性会调用主对象的 get_valueset_value 方法。这样一来,bound_value 看起来就像是 Slave 类的一个普通成员变量。

class Slave(object):
    def __init__(self,getfunc,setfunc):
        self.getfunc = getfunc
        self.setfunc = setfunc
    @property
    def bound_value(self):
        return self.getfunc()

    @bound_value.setter
    def bound_value(self, value):
        self.setfunc(value)

然后,你可以像使用成员变量一样,直接用 slave.bound_value 来获取或设置这个值。

撰写回答