1

So here is a bit of code to better understand what I'm trying to do (Real-world example on the end):

Let's say there is some low level class:

class Low:

    def __init__(self):
        self.value = 10

and there is High level class in which one of its attributes is Low level object:

class High:

    def __init__(self, LOW):

        self._value = 5
        self._LOW = LOW

    # integer attribute

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, new_value):
        self._value = new_value
        self.print_method()

    def print_method(self):
        print(self._value)

    # object attribute

    @property
    def LOW(self):
        return self._LOW

    @LOW.setter
    def LOW(self, NEW_LOW):
        self._LOW = NEW_LOW
        self.print_method_2()

    def print_method_2(self):
        print(self._LOW.value)

So if I want to automatically call print_method() by changing value of High class that is an integer, I can do:

LOW = Low()      # create Low level object
HIGH = High(LOW) # create High level object

HIGH.value = 100 # value is set to 100 -> and 100 will be printed (integer attribute change)

Similarly, If I want to call print_method_2() by changing High's object attribute that is also an object, I can do:

LOW = Low()      # create Low level object
HIGH = High(LOW) # create High level object

LOW_2 = Low()
HIGH.LOW = LOW_2 # LOW is set to LOW_2 and 5 is printed (Object attribute change)

But I don't want to do this manually. I would want to edit Low level object and automatically call print_method_2().

Something like:

LOW = Low()
HIGH = High(LOW)

LOW.value = 13 # automatically call print_method_2() in High -> print 13

Ideally, this Low level object should be attribute of several different High level object, and whenever it changes all of those High level objects should change. I know that custom objects are mutable, so this one change of Low level object should automatically change all of those High level objects. Any ideas how to do that?

Real-world example: Lets say I have Ground class that contains data about 3D ground. This object is attribute of Grass, Trees, Rivers... objects. Everything depends on Ground. So if I edit Ground's altitude I don't want to set Ground again to Grass, Trees, Rivers... objects. I want them to detect Ground's change and edit automatically.

  • you already have all the setters, so you can check what setter was used then called whatever method you want. You can also achieve similar result by implementing `__setattr__` – DeepSpace Jan 15 '20 at 09:12
  • Well, then I would need threads to constantly check if something is set? If that is true, then performance would suffer – Nemanja Stojanovic Jan 15 '20 at 09:17
  • I'm not sure I follow. You don't need to check anything. If the setter was called it means something was (or about to be) changed – DeepSpace Jan 15 '20 at 09:18
  • But the setter won't be called. If I edit low level object, why would the setter of high level object be called? How can high level object know if its attribute's attribute has changed? – Nemanja Stojanovic Jan 15 '20 at 09:21

1 Answers1

0

The easiest way to achieve this is probably writing a setter method for your HIGH-object, which sets HIGH.LOW.value and calls your method. So something like this:

class High:
    def setLowValue(value):
        self.LOW.value = value
        self.print_method_2()

Another way would be implementing somekind of event listener which fires an event when the value changes. But this is also beyond my scope in Python.

DerHamm
  • 173
  • 8
  • But then I would have to edit low level object through High level object. What I want to do is to edit Low level object and that should automatically edit High Level objects. That is more intuitive. Custom objects are mutable, so if I edit Low level object, High level object would point to the new changed Low level object. There is no issue with that. Only problem is how can High level object know that attribute (object) it is pointing to has changed – Nemanja Stojanovic Jan 15 '20 at 09:33
  • I see your point here. The problem is, that it is considered bad practice, when High-Class has to know about functionality of Low-Class. You are creating a dependency with that, which may cause even more problems while working on a project. Edit: You may take a look at https://stackoverflow.com/questions/1092531/event-system-in-python as it might be, what you are looking for. Implementing a simple observer could do the trick in your case. – DerHamm Jan 15 '20 at 09:41