decorator_4.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. from functools import wraps
  2. import time
  3. '''
  4. Такой декоратор работать не будет
  5. '''
  6. '''
  7. def html_tag(func, name_tag='h1'):
  8. def inner(*args, **kwargs):
  9. result = func(*args, **kwargs)
  10. return f'<{name_tag}>{result}</{name_tag}>'
  11. return inner
  12. '''
  13. '''
  14. def decorator_factory(a, b):
  15. print('Запуск функции создания декоратора')
  16. def decorator(fn):
  17. print('Запуск декоратора')
  18. def wrapper(*args, **kwargs):
  19. print('Запуск функции wrapper')
  20. print('Переданные аргументы: ', a, b)
  21. return fn(*args, **kwargs)
  22. return wrapper
  23. return decorator
  24. '''
  25. '''
  26. Можно раскрыть следующей записью
  27. decorator = decorator_factory() # получаем декоратор из decorator_factory
  28. original_func = decorator(original_func) # декорируем
  29. Или есть еще вариант
  30. original_func = decorator_facotry()(original_func)
  31. '''
  32. '''
  33. @decorator_factory(10, 20) # Обратите внимание на оператор вызова
  34. def original_func():
  35. print('Запуск оригинальной функции')
  36. '''
  37. '''
  38. Рабочий вариант декоратора
  39. '''
  40. def html_tag(name_tag='h1'):
  41. def decorator(func):
  42. @wraps(func)
  43. def inner(*args, **kwargs):
  44. result = func(*args, **kwargs)
  45. return f'<{name_tag}>{result}</{name_tag}>'
  46. return inner
  47. return decorator
  48. @html_tag(name_tag='table')
  49. @html_tag('td')
  50. @html_tag()
  51. @html_tag('p')
  52. def say_hello_to(name, surname):
  53. return f'Hello {name} {surname}'
  54. def cached_with_expiry(expiry_time):
  55. def decorator(original_function):
  56. cache = {} # словарь для хранения кеша
  57. def wrapper(*args, **kwargs):
  58. key = (*args, *kwargs.items())
  59. if key in cache:
  60. cached_value, cached_timestamp = cache[key]
  61. if time.time() - cached_timestamp < expiry_time:
  62. return f'[CACHED] - {cached_value}'
  63. result = original_function(*args, **kwargs)
  64. cache[key] = (result, time.time())
  65. return result
  66. return wrapper
  67. return decorator
  68. @cached_with_expiry(expiry_time=5)
  69. def get_product(x, y):
  70. return x*y
  71. def multiply_result_by(n):
  72. def decorator(func):
  73. @wraps(func)
  74. def wrapper(*args, **kwargs):
  75. result = func(*args, **kwargs)
  76. return n*result
  77. return wrapper
  78. return decorator
  79. def limit_query(n):
  80. def decorator(func):
  81. limit = n
  82. @wraps(func)
  83. def wrapper(*args, **kwargs):
  84. nonlocal limit
  85. if limit == 0:
  86. print(f'Лимит вызовов закончен, все {n} попытки израсходованы')
  87. return None
  88. else:
  89. limit -= 1
  90. return func(*args, **kwargs)
  91. return wrapper
  92. return decorator
  93. @limit_query(3)
  94. def add(a: int, b: int):
  95. return a + b
  96. def monkey_patching(arg='Monkey', kwarg='patching'):
  97. def decorator(func):
  98. @wraps(func)
  99. def wrapper(*_args, **_kwargs):
  100. patched_args = (arg, )*len(_args)
  101. patched_kwargs = {key:kwarg for key, _ in _kwargs.items()}
  102. return func(*patched_args, **patched_kwargs)
  103. return wrapper
  104. return decorator
  105. @monkey_patching(kwarg='Duper')
  106. def print_args_kwargs(*args, **kwargs):
  107. for i, value in enumerate(args):
  108. print(i, value)
  109. for k, v in sorted(kwargs.items()):
  110. print(f'{k} = {v}')
  111. def pass_arguments(*args_, **kwargs_):
  112. def decorator(func):
  113. @wraps(func)
  114. def wrapper(*args, **kwargs):
  115. print(args_, kwargs_)
  116. return func(*args, **kwargs)
  117. return wrapper
  118. return decorator
  119. @pass_arguments(s='Когда', w='-', r='нибудь!')
  120. def concatenate(**kwargs):
  121. result = ""
  122. for arg in kwargs.values():
  123. result += str(arg)
  124. return result
  125. def main():
  126. print(concatenate(a="Я", b="Выучу", c="Этот", d="Питон", e="!"))
  127. # print_args_kwargs(1, 2, 3, 4, b=300, w=40, t=50, a=100)
  128. '''
  129. print(get_product(23, 5)) # Вычисляем в первый раз
  130. print(get_product(23, 5)) # Во второй раз срабатывает кеш
  131. time.sleep(5)
  132. print(get_product(23, 5)) # Кеш просрочился, поэтому вновь вычисляется значение
  133. '''
  134. # original_func()
  135. # print(say_hello_to('Vasiliy', 'Ytkin'))
  136. if __name__ == '__main__':
  137. main()