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}' 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}' 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 @limit_query(3) def add(a: int, b: int): return a + b def main(): print(add(4, 5)) print(add(5, 8)) print(add(9, 43)) print(add(10, 33)) print(add.__name__) ''' 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()