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.

3
  • 1
    see ../1904351/python-observer-pattern-examples-tips or this Commented Dec 25, 2013 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. Commented Dec 25, 2013 at 13:56
  • Just use a property. Commented Dec 25, 2013 at 15:13

1 Answer 1

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
Sign up to request clarification or add additional context in comments.

3 Comments

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 You might wanna look at the page commented by behzad.nouri
Thank you thefourtheye and behzad.nouri, this should work. I can adapt the code posted on the wikibook links to get the desired behaviour.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.