2

I cannot find a proper way of decorating a @property.setter decorator inside a Python class.

To avoid copy-pasting of code, I decided to decorate @property.setter function in my project's "Settings" module. So "Setting" module, has an ability of auto-saving newly added/changed settings.

The issue is that to enable auto-saving ability I have to set a certain flag:

self.changed = True

every time a setting is modified.

But, I don't think that adding that flag to every @property.setter is a good idea, since there might be a case when I have to do more logic before save is performed, and in that case I will have to paste this logic to every @property.setter I already have (which is not efficient imo).

What I want is to replace:

    @baud_rate.setter
    def baud_rate(self, value):
        self.changed = True
        self._baud_rate = value

with:

    @setting_decorator
    @baud_rate.setter
    def baud_rate(self, value):
        self._baud_rate = value

But I have no clue on how to implement such decorator.

quamrana
  • 37,849
  • 12
  • 53
  • 71
  • It's not clear what your goal is. 1. `property.setter` is not a regular function but method of a descriptor class. Descriptor is some special kind of decorators. 2. How you use `property` right now seems completely unnecessary. 3. Maybe you should look at `__setattr__` method if you want to keep track of changes for any attribute. –  Apr 11 '19 at 10:35

1 Answers1

0

I think descriptor is what you need. see this example:

class Settings:
    def __init__(self, name):
        self.name = name

    def __get__(self, instance, owner):
        return instance.__dict__[self.name]

    def __set__(self, instance, value):
        instance.__dict__['changed'] = True
        instance.__dict__[self.name] = value


class ClassWithSetting:

    def __init__(self, baud_rate):
        self.__class__.baud_rate = Settings('baud_rate')
        self.baud_rate = baud_rate

And for more information check doc because you can have better implementation depending on your python version.

Aliakbar Saleh
  • 649
  • 3
  • 10