Декораторы и замыкания
Декораторы функций
import functools # импорт модуля
import time # импорт модуля времени
def timer(func):
@functools.wraps(func) # сохранение метаданных декорируемой функции
def wrapper(*args, **kwargs):
start = time.time() # метка времени в секундах
result = func(*args, **kwargs) # присваивание
elapsed = time.time() - start # метка времени в секундах
print(f"{func.__name__} заняла {elapsed:.3f}s") # вывод в консоль
return result # возврат значения
return wrapper # возврат значения
@timer
def slow_add(a, b):
"""Складывает два числа."""
time.sleep(0.5) # пауза
return a + b # возврат значения
slow_add(1, 2) # slow_add заняла 0.501s
print(slow_add.__name__) # slow_add (без wraps было бы 'wrapper')
Декораторы с параметрами
def repeat(n):
def decorator(func):
@functools.wraps(func) # сохранение метаданных декорируемой функции
def wrapper(*args, **kwargs):
for _ in range(n): # цикл по элементам
result = func(*args, **kwargs) # присваивание
return result # возврат значения
return wrapper # возврат значения
return decorator # возврат значения
@repeat(3)
def say(message):
print(message) # вывод в консоль
say("Привет!")
Декораторы классов
def add_repr(cls):
def __repr__(self):
items = ", ".join(f"{k}={v}" for k, v in self.__dict__.items()) # получение пар ключ-значение
return f"{cls.__name__}({items})" # возврат значения
cls.__repr__ = __repr__
return cls # возврат значения
@add_repr
class User:
def __init__(self, name, age):
self.name = name # обращение к атрибуту экземпляра
self.age = age # обращение к атрибуту экземпляра
user = User("Анна", 30) # присваивание
print(user) # User(name=Анна, age=30)
Декоратор для методов класса
def log_call(method):
@functools.wraps(method) # сохранение метаданных декорируемой функции
def wrapper(self, *args, **kwargs):
print(f"Вызов {method.__name__}") # вывод в консоль
return method(self, *args, **kwargs) # возврат значения
return wrapper # возврат значения
class Service:
@log_call
def process(self, data):
return f"Обработка: {data}" # возврат значения
Замыкания (closures)
def multiplier(factor):
def multiply(x):
return x * factor # возврат значения
return multiply # возврат значения
double = multiplier(2) # присваивание
triple = multiplier(3) # присваивание
print(double(5)) # 10
print(triple(5)) # 15
functools.partial — частичное применение
from functools import partial # импорт модуля
def power(base, exp):
return base ** exp # возврат значения
square = partial(power, exp=2) # присваивание
cube = partial(power, exp=3) # присваивание
print(square(5)) # 25
print(cube(5)) # 125