1

Let's consider the following example:

class SubClass:
    def __init__(self):
        self._param = None

    @property
    def param(self):
        print('read param')
        return self._param

    @param.setter
    def param(self, value):
        print('set param')
        self._param = value


class MainClass:
    def __init__(self):
        self._var = SubClass()

    @property
    def var(self):
        print('read var')
        return self._var

    @var.setter
    def var(self, value):
        print('set var')
        self._var = value

If I do:

cls = MainClass()
cls.var.param = 3

I obtain:

'read var'
'set param'

How can I make MainClass aware that var.param has changed?

Useful additional info: consider that in my actual code param is not a scalar but an array with hundreds of elements, so I would like to avoid to create a copy and then just compare them. Moreover, param and var are not the only properties.

mauro
  • 504
  • 3
  • 14
  • why do you need this in the first place? looks like an XY problem to me – Azat Ibrakov Dec 01 '21 at 11:02
  • to make it simple, because I need to make some operations in ```MainClass``` but only if ```var.param``` has changed. – mauro Dec 01 '21 at 11:07
  • You could consider using an observer class to track changes. See e.g. https://stackoverflow.com/questions/22878220/looking-for-a-solution-to-detect-value-change-in-class-attribute-with-a-list-and – match Dec 01 '21 at 11:14

1 Answers1

0

One approach is to pass a method from MainClass as an argument when instantiating SubClass, and have SubClass call it whenever it changes a variable:

class SubClass:
    def __init__(self, changed):
        self._param = None
        self.changed = changed

    @property
    def param(self):
        print('read param')
        return self._param

    @param.setter
    def param(self, value):
        print('set param')
        self._param = value
        self.changed('param')


class MainClass:
    def __init__(self):
        self._var = SubClass(self.changed)
    
    def changed(self, name):
        print("Subclass changed: ", name, getattr(self._var, name))

    @property
    def var(self):
        print('read var')
        return self._var

    @var.setter
    def var(self, value):
        print('set var')
        self._var = value


m = MainClass()
m.var.param = 'test'
match
  • 10,388
  • 3
  • 23
  • 41