0

In Python, what is the best way of creating an object variable of Object A which is dependent on a variable of Object B and is updated automatically whenever the variable of Object B changes?

Simple example:

class house:
    house_size = 100

class room:
    room_size = 30

house1 = house()
room1 = room()

house1.house_size = room1.room_size * 10
print house1.house_size #returns 300

room1.room_size = 50
print house1.house_size #still returns 300, but I would like it to return 500

In the example above a relationship between house1.house_size and room1.room_size is defined. However, this is only interpreted once. What is the best way to establish a permanent relationship between the two variables to ensure that house1.house_size is updated automatically whenever room1.room_size changes subsequently?

Edit: To clarify, I am looking for a generic solution whereby an object validates whether all its dependencies are still "valid" whenever the value of its object variable is being read. In the example above the object variable house1.house_size is dependent on room1.room_size

You can think of these dependencies similar to a spreadsheet application: For example, cell A1 might be defined as =B1+B2+B3 and B1 in turn might be defined as =C1*2. Whenever the value of cell A1 is being read then it will check if any of B1, B2 or B3 have changed. If so, then the value of A1 will be re-calculated before the value is being returned. So in Python I am looking for an event handler which is triggered whenever the value of house1.house_size is being read so that its value can be recomputed before being returned.

The answer should be generic enough such that whole dependency trees of objects can be handled whereby each node in the tree checks by itself whether all values of all object variables it depends on are still valid and otherwise recalculates.

Michael
  • 407
  • 2
  • 6
  • 11
  • 1
    see [../1904351/python-observer-pattern-examples-tips](http://stackoverflow.com/questions/1904351/python-observer-pattern-examples-tips) or [this](https://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Observer) – behzad.nouri Dec 25 '13 at 13:56
  • 1
    This is a very strange object model. You should have a `House` class that contains a list of `Room` class instances, each of which has a `size`, from which the `House` instance can calculate its own size. Also, `size` should be an instance variable, not a class variable. – Tim Pietzcker Dec 25 '13 at 13:56
  • Just use a `property`. – Eryk Sun Dec 25 '13 at 15:13

1 Answers1

2

You have to establish a relationship between the room and the house model. In this answer, I have made the room object to accept the house object as one of the parameters and whenever the room_size parameter is set, it will update the house_size as well.

class house:
    house_size = 100

class room:
    def __init__(self, house_object):
        self.house_object = house_object
        self.room_size = self.house_object.house_size / 10

    def __setattr__(self, key, value):
        self.__dict__[key] = value
        if key == "room_size":
            self.house_object.house_size = self.room_size * 10

house1 = house()
room1 = room(house1)

room1.room_size = 50
print house1.house_size
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
  • Thank you, this is helpful and `__setattr__` looks like a good starting point. In the example the `house1` object depends on the `room1` object. Your solution is updating `house1` whenever `room1` changes. While this will work for a 1:1 relationship, I am looking for a more generic solution whereby on `house1` validates whether all its dependencies (including the value of `room1.room_size`) are still "valid" whenever the value of `house1.house_size` is being read. I have edited my original question to clarify this point. – Michael Dec 25 '13 at 14:55
  • @Michael You might wanna look at the page commented by behzad.nouri – thefourtheye Dec 25 '13 at 15:04
  • Thank you thefourtheye and behzad.nouri, this should work. I can adapt the code posted on the wikibook links to get the desired behaviour. – Michael Dec 25 '13 at 15:08