1

I'm trying to keep track if any of the attributes of an object have been changed so I can keep a stack of object 'versions' that the user can revert to in case he needs (like a Undo\Redo feature).

For that, I figured I could use getters and setters for every one of the attributes, and have the setters call a function that keeps track of the changes. Since I have over 20 attributes, I'm trying to figure to do that without having to write 20 @property, @attribute.setter function pairs.

Something along the code below seems ideal. However, you can't use a variable as a function name and I can't figure out a good way to pass self to the inner attr and attr_setter functions.

class MyClass:
    def __init__(self, start, end):
        self._start = start
        self._end = end

        self.create_getset()

    def create_getset(self):
        for attr in self.__dict__:
            attr = attr[1:]
            @property
            def attr(self):
                print(f'{attr} getter is called')
                return self._attr

            @attr.setter
            def attr_setter(self, value):
                setattr(self, attr, value)
                # function to keep track of changes

Given that, some questions:

(1) Is this a good way to add getters and setters to all the attributes? Is there a better way?
(2) Is this a reasonably good way to keep track of the changes to the attributes?

If (1) and (2), then how can I make it work? How can I use attribute names as variables to create the functions needed to add getters and setters?

  • 1
    I think [this](https://stackoverflow.com/a/19907816/9472529) will help you – Yoav Ben Haim Jul 10 '21 at 20:15
  • Thanks! That indeed answers the question. However, I also need to call methods on the wrapped object, and it seems that it isn't possible with the solution on the link. I'll try researching on proxy classes to see if I can figure it out. – Felipe Martins Jul 11 '21 at 11:44

0 Answers0