[Python] Decorating python properties with an observable pattern

Discussão em 'Python' iniciado por Stack, Novembro 29, 2024.

  1. Stack

    Stack Membro Participativo

    I'm trying to create an observable decorator that adds the method "add_observer" to a property. The main issue I'm having is that I do not know how to treat the getter. It would be amazing if I could extend the underlying property with the method somehow.

    class observable:
    def __init__(self, fget):
    self.observers = []
    self.fget = fget
    self.fset = None
    self.name = fget.__name__

    def add_observer(self, observer):
    self.observers.append(observer)

    def setter(self, fset):
    self.fset = fset
    return self

    def __set__(self, obj, value) -> None:

    if self.fset is None:
    raise AttributeError(f"Setter not defined for property {self.name}")
    self.fset(obj, value)

    for observer in self.observers:
    observer(value)

    def __get__(self, obj, objtype=None):
    return self


    class Options:

    def __init__(self):
    self._debug: bool = False

    @observable
    def debug(self) -> bool:
    return self._debug

    @debug.setter
    def debug(self, debug: bool):
    self._debug = debug


    opt = Options()
    print(opt.debug)
    opt.debug.add_observer(lambda value: print(f"Debug is {value}"))
    opt.debug = True
    opt.debug = False


    <__main__.observable object at 0x7f446f854500>
    Debug is True
    Debug is False


    I cannot use opt.debug as a boolean value. I tried alternatives such as modifying the owner with owner.add_observable(owner.debug, lambda x: 'hello!') which is pretty close to what I want but not close enough. Mostly because I wanted autocomplete to work.

    Also, I'm getting a shadowing error on the IDE that @property does not trigger, how come?: [​IMG]

    Continue reading...

Compartilhe esta Página