functools.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. class cache:
  2. def __init__(self, f):
  3. self.f = f
  4. self.cache = {}
  5. def __call__(self, *args):
  6. if args not in self.cache:
  7. self.cache[args] = self.f(*args)
  8. return self.cache[args]
  9. class lru_cache:
  10. def __init__(self, maxsize=128):
  11. self.maxsize = maxsize
  12. self.cache = {}
  13. def __call__(self, f):
  14. def wrapped(*args):
  15. if args in self.cache:
  16. res = self.cache.pop(args)
  17. self.cache[args] = res
  18. return res
  19. res = f(*args)
  20. if len(self.cache) >= self.maxsize:
  21. first_key = next(iter(self.cache))
  22. self.cache.pop(first_key)
  23. self.cache[args] = res
  24. return res
  25. return wrapped
  26. def reduce(function, sequence, initial=...):
  27. it = iter(sequence)
  28. if initial is ...:
  29. try:
  30. value = next(it)
  31. except StopIteration:
  32. raise TypeError("reduce() of empty sequence with no initial value")
  33. else:
  34. value = initial
  35. for element in it:
  36. value = function(value, element)
  37. return value
  38. class partial:
  39. def __init__(self, f, *args, **kwargs):
  40. self.f = f
  41. if not callable(f):
  42. raise TypeError("the first argument must be callable")
  43. self.args = args
  44. self.kwargs = kwargs
  45. def __call__(self, *args, **kwargs):
  46. kwargs.update(self.kwargs)
  47. return self.f(*self.args, *args, **kwargs)