123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- from functools import wraps
- import time
- '''
- Такой декоратор работать не будет
- '''
- '''
- def html_tag(func, name_tag='h1'):
- def inner(*args, **kwargs):
- result = func(*args, **kwargs)
- return f'<{name_tag}>{result}</{name_tag}>'
- return inner
- '''
-
- '''
- def decorator_factory(a, b):
- print('Запуск функции создания декоратора')
- def decorator(fn):
- print('Запуск декоратора')
- def wrapper(*args, **kwargs):
- print('Запуск функции wrapper')
- print('Переданные аргументы: ', a, b)
- return fn(*args, **kwargs)
- return wrapper
- return decorator
- '''
- '''
- Можно раскрыть следующей записью
- decorator = decorator_factory() # получаем декоратор из decorator_factory
- original_func = decorator(original_func) # декорируем
- Или есть еще вариант
- original_func = decorator_facotry()(original_func)
- '''
- '''
- @decorator_factory(10, 20) # Обратите внимание на оператор вызова
- def original_func():
- print('Запуск оригинальной функции')
- '''
- '''
- Рабочий вариант декоратора
- '''
- def html_tag(name_tag='h1'):
- def decorator(func):
- @wraps(func)
- def inner(*args, **kwargs):
- result = func(*args, **kwargs)
- return f'<{name_tag}>{result}</{name_tag}>'
- return inner
- return decorator
- @html_tag(name_tag='table')
- @html_tag('td')
- @html_tag()
- @html_tag('p')
- def say_hello_to(name, surname):
- return f'Hello {name} {surname}'
- def cached_with_expiry(expiry_time):
- def decorator(original_function):
- cache = {} # словарь для хранения кеша
- def wrapper(*args, **kwargs):
- key = (*args, *kwargs.items())
- if key in cache:
- cached_value, cached_timestamp = cache[key]
- if time.time() - cached_timestamp < expiry_time:
- return f'[CACHED] - {cached_value}'
-
- result = original_function(*args, **kwargs)
- cache[key] = (result, time.time())
- return result
- return wrapper
- return decorator
- @cached_with_expiry(expiry_time=5)
- def get_product(x, y):
- return x*y
- def multiply_result_by(n):
- def decorator(func):
- @wraps(func)
- def wrapper(*args, **kwargs):
- result = func(*args, **kwargs)
- return n*result
- return wrapper
- return decorator
- def limit_query(n):
- def decorator(func):
- limit = n
- @wraps(func)
- def wrapper(*args, **kwargs):
- nonlocal limit
- if limit == 0:
- print(f'Лимит вызовов закончен, все {n} попытки израсходованы')
- return None
- else:
- limit -= 1
- return func(*args, **kwargs)
- return wrapper
- return decorator
- def monkey_patching(arg='Monkey', kwarg='patching'):
- def decorator(func):
- @wraps(func)
- def wrapper(*_args, **_kwargs):
- patched_args = (arg, )*len(_args)
- patched_kwargs = {key:kwarg for key, _ in _kwargs.items()}
- return func(*patched_args, **patched_kwargs)
- return wrapper
- return decorator
- @monkey_patching(kwarg='Duper')
- def print_args_kwargs(*args, **kwargs):
- for i, value in enumerate(args):
- print(i, value)
- for k, v in sorted(kwargs.items()):
- print(f'{k} = {v}')
- def pass_arguments(*args_, **kwargs_):
- def decorator(func):
- @wraps(func)
- def wrapper(*args, **kwargs):
- print(args_, kwargs_)
- return func(*args, **kwargs)
- return wrapper
- return decorator
- @pass_arguments(s='Когда', w='-', r='нибудь!')
- def concatenate(**kwargs):
- result = ""
- for arg in kwargs.values():
- result += str(arg)
- return result
- def pass_arguments(*args_, **kwargs_):
- def decorator(func):
- @wraps(func)
- def wrapper(*args, **kwargs):
- new_args = args + args_
- new_kwargs = kwargs | kwargs_
- return func(*new_args, **new_kwargs)
- return wrapper
- return decorator
- def convert_to(type_):
- def decorator(func):
- @wraps(func)
- def wrapper(*args, **kwargs):
- return type_(func(*args, **kwargs))
- return wrapper
- return decorator
- @convert_to(str)
- def add_values(a, b):
- return a + b
- '''
- def validate_all_args_str(func):
- def wrapper(*args, **kwargs):
- if len([True for x in args if type(x) == str]) == len(args):
- return func(*args, **kwargs)
- else:
- print('Все аргументы должны быть строками')
- return wrapper
- '''
- def validate_all_args(type_):
- def decorator(func):
- @wraps(func)
- def wrapper(*args, **kwargs):
- if len([True for x in args if type(x) == type_]) == len(args):
- return func(*args, **kwargs)
- else:
- print(f'Все аргументы должны принадлежать типу {type_}')
- return wrapper
- return decorator
- @validate_all_args(set)
- def print_args_kwargs(*args, **kwargs):
- for i, value in enumerate(args):
- print(i, value)
- for k, v in sorted(kwargs.items()):
- print(f'{k} = {v}')
- def compose(*args_):
- def decorator(func):
- @wraps(func)
- def wrapper(*args, **kwargs):
- result = func(*args, **kwargs)
- for f in args_:
- result = f(result)
- return result
- return wrapper
- return decorator
- def double_it(a):
- return a * 2
- def increment(a):
- return a + 1
-
- @compose(double_it, increment)
- def get_sum(*args):
- return sum(args)
- def add_attrs(**kwargs_):
- def decorator(func):
- @wraps(func)
- def wrapper(*args, **kwargs):
- return func(*args, **kwargs)
- for key, value in kwargs_.items():
- setattr(wrapper, key, value)
- return wrapper
- return decorator
- @add_attrs(test=True, ordered=True)
- def add(a, b):
- return a + b
- def main():
- print(add(10, 5))
- print(add.test)
- print(add.ordered)
- # print(get_sum(5))
- # print(get_sum(20, 10))
- # print(get_sum(5, 15, 25))
- # print_args_kwargs([], [1], [1, 2], b=set(), w=set())
- # print_args_kwargs(1, 2, 3, 4, b=300, w=40, t=50, a=100)
- # result = add_values(10, 20)
- # print(f"Результат: {result}, тип результата {type(result)}")
- # print(add(5, 4, 6, a=1, b=2))
- # print(concatenate(a="Я", b="Выучу", c="Этот", d="Питон", e="!"))
- # print_args_kwargs(1, 2, 3, 4, b=300, w=40, t=50, a=100)
- '''
- print(get_product(23, 5)) # Вычисляем в первый раз
- print(get_product(23, 5)) # Во второй раз срабатывает кеш
- time.sleep(5)
- print(get_product(23, 5)) # Кеш просрочился, поэтому вновь вычисляется значение
- '''
- # original_func()
- # print(say_hello_to('Vasiliy', 'Ytkin'))
-
- if __name__ == '__main__':
- main()
|