Advertisement
DeaD_EyE

Getter/Setter class to fix a problem with already existing code in a project

Aug 21st, 2021 (edited)
2,161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.84 KB | None | 0 0
  1. import time
  2. from collections import deque
  3. from itertools import islice
  4. from operator import itemgetter
  5.  
  6.  
  7. class Property:
  8.     """
  9.    Getter/Setter class which must be set multiple times
  10.    with an equal object to fit the maxlen.
  11.    A timeout make it possible to remove too old objects.
  12.  
  13.    The condition is only fulfilled if:
  14.        - all objects are equal
  15.        - the time delta between the objects must be lesser than `timeout`
  16.  
  17.    If the condition is not fulfilled, the dtype() will return instead.
  18.    """
  19.  
  20.     def __init__(self, maxlen=2, timeout=2, dtype=str):
  21.         self._instances = {}
  22.         self._maxlen = maxlen
  23.         self.timeout = timeout
  24.         self.dtype = dtype
  25.  
  26.     def _get_diffs(self, instance):
  27.         return [t2 - t1 for (_, t1), (_, t2) in self._zip_pairwise(instance)]
  28.  
  29.     def _zip_pairwise(self, instance):
  30.         data = self._instances[instance]
  31.         return zip(islice(data, 0, None), islice(data, 1, None))
  32.  
  33.     def _remove_old(self, instance):
  34.         diffs = self._get_diffs(instance)
  35.         for idx, diff in enumerate(diffs):
  36.             if diff > self.timeout:
  37.                 del self._instances[instance][idx]
  38.  
  39.     def _all_eq(self, instance):
  40.         return all(a == b for (a, _), (b, _) in self._zip_pairwise(instance))
  41.  
  42.     def __get__(self, obj, objtype=None):
  43.         if obj in self._instances:
  44.  
  45.             data = self._instances[obj]
  46.  
  47.             if len(data) == self._maxlen and self._all_eq(obj):
  48.                 return data[-1][0]
  49.  
  50.         return self.dtype()
  51.  
  52.     def __set__(self, obj, value):
  53.         if obj not in self._instances:
  54.             self._instances[obj] = deque(maxlen=self._maxlen)
  55.  
  56.         self._instances[obj].append((value, time.monotonic()))
  57.         self._remove_old(obj)
  58.  
  59.  
  60. class Test:
  61.     error = Property(maxlen=3, timeout=2, dtype=str)
  62.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement