1

Suppose I have a single instance of a master object that contains a set of parameters, then multiple instances of slave objects that should be able to access and modify the attributes of the master. In my particular case the slaves are wxPython GUI objects, where there might be multiple GUI controls that can modify the same parameter.

Obviously this is trivial if I explicitly refer to master.parameter when the slave wants to update it. However I would really prefer not to have to do this, since it would require me to write different functions to handle events from each slave object.

I'm currently doing something like this, with the master having separate get_value and set_value methods for each property:

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()

What I really want to be able to do is set something like slave.bound_value, which would behave like a pointer to master.value, so that when any slave modifies its bound_value then the corresponding attribute of master is updated. I'm fully aware that Python doesn't support pointers, but I was wondering if there's a nice Pythonic way to achieve the same thing?

ali_m
  • 71,714
  • 23
  • 223
  • 298
  • 2
    "I'm fully aware that Python doesn't support pointers" - every name in Python is a reference. This is pretty trivial to do in a number of ways. If you make a mutable object for the value you want, then the slaves can just store a reference to it as well as the master, and it will function exactly as you want. – Gareth Latty Feb 14 '13 at 16:08
  • 2
    Note that Python is not Java; we rarely need to use getters and setters. When we do, we wrap those in a `@property` to hide the fact that we are using getters and setters. – Martijn Pieters Feb 14 '13 at 16:15
  • @Lattyware I meant pointers that function like pointers in C or C++, as discussed [here](http://stackoverflow.com/questions/3106689/pointers-in-python) – ali_m Feb 14 '13 at 16:16
  • I'm still having a bit of a tough time figuring out what you want. You want to create a `Slave` object delegates actions on attributes which start with `bound_` to the `Master`? – mgilson Feb 14 '13 at 16:16
  • @mgilson No, I want to create an instance of `Slave` that is 'bound' to an attribute of an instance of `Master`, so that when `slave` updates its `bound_value` attribute, then the corresponding attribute of `master` also changes – ali_m Feb 14 '13 at 16:20
  • @ali_m -- Yeah, but does a slave only bind itself to a single attribute of `Master` or all of master's attributes? – mgilson Feb 14 '13 at 16:33
  • @mgilson For the moment I would only really need to bind to a single attribute – ali_m Feb 14 '13 at 16:41

2 Answers2

2

You can accomplish what your are asking by making bound_value a property attribute that wraps the calls to the master's get_value and set_value methods. This will make it appear that bound_value is just a member variable of the Slave class.

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)

Then, you can simply refer to slave.bound_value like it is a member variable whenever you want to get or set the value.

bogatron
  • 18,639
  • 6
  • 53
  • 47
  • Ah, I had previously tried making `master.value` a property attribute, which obviously didn't do what I wanted since when I assigned `slave.bound_value = master.value` I was really just assigning the current value of `master.value` – ali_m Feb 14 '13 at 16:32
1

Thanks to bogatron for setting me on the right path - here's what I opted for in the end:

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()
ali_m
  • 71,714
  • 23
  • 223
  • 298