Python accumulate Enum values into list by accessing them

Viewed 33

I would like to be able to accumulate values of accessed variables into a list of that object. I was thinking of using Enum for it, as one of my requirement is to be able to use code completion in PyCharm and with Enum something like Keys.KEY_A.KEY_B in PyCharm always gives all the options of class Keys as code completion.

My expected behaviour is like this:


# define some class which holds all the possible values
class Keys(Enum):
   KEY_A = "a"
   KEY_B = "b"
   F4 = "f4"

if __name__ == "__main__":
  # when attribute is accessed, its value is stored internally in some list
  k1 = Keys().KEY_A.KEY_B
  print(k1.items())
  # ["a", "b"]
  k1.F4
  print(k1.items())
  # ["a", "b", "f4"]

  # when object is instantiated the list is empty
  k2 = Keys().KEY_A.F4
  print(k2.items())
  # ["a", "f4"]

The best solution I was able to do was

def cumulative_decorator(item):
    class cumul_property:
        def __init__(self, func):
            self.__doc__ = getattr(func, "__doc__")
            self.func = func

        def __get__(self, instance, owner):
            if not instance._items:
                return type(instance)(item)

            instance._items.append(item)
            return instance

    return cumul_property


class Cumulative:

  def __init__(key: str = None):
    self._items = [key] if key else []

  @cumulative_decorator(Keys.KEY_A)
  def KEY_A(self) -> "Cumulative":
    return self

But to implement every value as a property is "too wordy", and also code completion doesn't work correctly when made I parent class that implements basic behaviour, so that I can inherit from it and use this funcionality not only for Keys but also other classes. I was hoping to just implement one or two additional methods in the class Keys and solve this problem, but as Enum is returning the same class for the same value if I added any internal list, it just accumulated more and more with every access.

I'm looking for an advice how I could implement my "expected behaviour".

0 Answers
Related