utils.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import warnings
  2. def saveit(func):
  3. """A decorator that caches the return value of a function"""
  4. name = '_' + func.__name__
  5. def _wrapper(self, *args, **kwds):
  6. if not hasattr(self, name):
  7. setattr(self, name, func(self, *args, **kwds))
  8. return getattr(self, name)
  9. return _wrapper
  10. cacheit = saveit
  11. def prevent_recursion(default):
  12. """A decorator that returns the return value of `default` in recursions"""
  13. def decorator(func):
  14. name = '_calling_%s_' % func.__name__
  15. def newfunc(self, *args, **kwds):
  16. if getattr(self, name, False):
  17. return default()
  18. setattr(self, name, True)
  19. try:
  20. return func(self, *args, **kwds)
  21. finally:
  22. setattr(self, name, False)
  23. return newfunc
  24. return decorator
  25. def ignore_exception(exception_class):
  26. """A decorator that ignores `exception_class` exceptions"""
  27. def _decorator(func):
  28. def newfunc(*args, **kwds):
  29. try:
  30. return func(*args, **kwds)
  31. except exception_class:
  32. pass
  33. return newfunc
  34. return _decorator
  35. def deprecated(message=None):
  36. """A decorator for deprecated functions"""
  37. def _decorator(func, message=message):
  38. if message is None:
  39. message = '%s is deprecated' % func.__name__
  40. def newfunc(*args, **kwds):
  41. warnings.warn(message, DeprecationWarning, stacklevel=2)
  42. return func(*args, **kwds)
  43. return newfunc
  44. return _decorator
  45. def cached(count):
  46. """A caching decorator based on parameter objects"""
  47. def decorator(func):
  48. return _Cached(func, count)
  49. return decorator
  50. class _Cached(object):
  51. def __init__(self, func, count):
  52. self.func = func
  53. self.cache = []
  54. self.count = count
  55. def __call__(self, *args, **kwds):
  56. key = (args, kwds)
  57. for cached_key, cached_result in self.cache:
  58. if cached_key == key:
  59. return cached_result
  60. result = self.func(*args, **kwds)
  61. self.cache.append((key, result))
  62. if len(self.cache) > self.count:
  63. del self.cache[0]
  64. return result