decorator_3.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. from functools import wraps
  2. from copy import deepcopy
  3. def no_side_effects_decorator(func):
  4. @wraps(func)
  5. def inner(*args, **kwargs):
  6. if isinstance(args[0], (list, dict, set)):
  7. copeed_args = tuple([args[0].copy(), *args[1:]])
  8. else:
  9. copeed_args = args
  10. return func(*copeed_args, **kwargs)
  11. return inner
  12. @no_side_effects_decorator
  13. def add_element(data, element):
  14. data.append(element)
  15. return data
  16. '''
  17. def add_element(data, key, value=None):
  18. data[key] = value
  19. return data
  20. '''
  21. def add_args(func):
  22. @wraps(func)
  23. def inner(*args, **kwargs):
  24. modifed_args = ('begin', ) + args + ('end', )
  25. return func(*modifed_args, **kwargs)
  26. return inner
  27. @add_args
  28. def concatenate(*args):
  29. """
  30. Возвращает конкатенацию переданных строк
  31. """
  32. return ', '.join(args)
  33. def explicit_args(func):
  34. @wraps(func)
  35. def inner(*args, **kwargs):
  36. if len(args):
  37. print('Вы не можете передать позиционные аргументы. Используйте именованный способ передачи значений')
  38. return
  39. else:
  40. return func(*args, **kwargs)
  41. return inner
  42. @explicit_args
  43. def add(a: int, b: int) -> int:
  44. '''Возвращает сумму двух чисел'''
  45. return a + b
  46. def reverse(func):
  47. @wraps(func)
  48. def inner(*args, **kwargs):
  49. reversed_args = args[::-1]
  50. return func(*reversed_args)
  51. return inner
  52. def monkey_patching(func):
  53. @wraps(func)
  54. def inner(*args, **kwargs):
  55. patched_args = ('Monkey', )*len(args)
  56. patched_kwargs = {key:'patching' for key, _ in kwargs.items()}
  57. return func(*patched_args, **patched_kwargs)
  58. return inner
  59. @monkey_patching
  60. def info_kwargs(**kwargs):
  61. """Выводит информацию о переданных kwargs"""
  62. for k, v in sorted(kwargs.items()):
  63. print(f'{k} = {v}')
  64. def counting_calls(func):
  65. @wraps(func)
  66. def inner(*args, **kwargs):
  67. inner.call_count += 1
  68. inner.calls.append({'args': args, 'kwargs':kwargs})
  69. return func(*args, **kwargs)
  70. setattr(inner, 'call_count', 0)
  71. setattr(inner, 'calls', [])
  72. return inner
  73. @counting_calls
  74. def add(a: int, b: int) -> int:
  75. '''Возвращает сумму двух чисел'''
  76. return a + b
  77. def check_count_args(func):
  78. @wraps(func)
  79. def inner(*args, **kwargs):
  80. if (len(args) + len(kwargs)) == 2:
  81. return func(*args, **kwargs)
  82. elif (len(args) + len(kwargs)) < 2:
  83. print("Not enough arguments")
  84. else:
  85. print("Too many arguments")
  86. return inner
  87. def cache_result(func):
  88. cache = {}
  89. @wraps(func)
  90. def inner(*args, **kwargs):
  91. nonlocal cache
  92. key = (args, tuple(kwargs.items()))
  93. if key in cache.keys():
  94. print(f'[FROM CACHE] Вызов {inner.__name__} = {cache[key]}')
  95. return cache[key]
  96. else:
  97. res = func(*args, **kwargs)
  98. cache[key] = res
  99. return res
  100. return inner
  101. @cache_result
  102. def multiply(a, b):
  103. return a * b
  104. def test(*args, **kwargs):
  105. pass
  106. def main():
  107. print(add(10, b=20))
  108. print(add(7, 5))
  109. print(add(12, 45))
  110. print('Количество вызовов =', add.call_count)
  111. print(add.calls[2])
  112. print(add(b=11, a=22))
  113. print(add.calls[3])
  114. # print(multiply(4, 5)) # Вызываем 1й раз функцию с аргументами 4 и 5. Идет сохранение результата
  115. # print(multiply(4, 5)) # При повторном вызове достаем из кеша
  116. # print(multiply(5, 8)) # Впервые вызывает с аргументами 5 и 8
  117. # print(multiply(5, 8)) # Достаем из кеша результат вызова multiply(5, 8)
  118. # print(multiply(5, 8)) # Вновь достаем из кеша
  119. # print(multiply(-3, 7)) # Впервые вычисляем результат вызова multiply(-3, 7), сохраняем в кеше
  120. # print(multiply(-3, 7)) # Достаем из кеша multiply(-3, 7)
  121. # info_kwargs(first_name="John", last_name="Doe", age=33)
  122. # info_kwargs(c=43, b= 32, a=32)
  123. # print(info_kwargs.__name__)
  124. # print(info_kwargs.__doc__.strip())
  125. # print(add(10, 20))
  126. # print(concatenate('hello', 'world', 'my', 'name is', 'Artem'))
  127. # print(concatenate('my', 'name is', 'Artem'))
  128. # print(concatenate.__name__)
  129. # print(concatenate.__doc__.strip())
  130. # my_list = [1, 2, 3]
  131. # print('Результат вызова =', add_element(my_list, 4))
  132. # print('Результат вызова =', add_element(my_list, 5))
  133. # my_dict = {1: 'Hello', 2: 'World'}
  134. # print('Результат вызова =', add_element(my_dict, 4, 'four'))
  135. # print(my_list)
  136. # print(add_element.__name__)
  137. # test(my_list)
  138. if __name__ == '__main__':
  139. main()