← Назад к вопросам
Как выполнить код до и после вызова функции в Python?
2.0 Middle🔥 231 комментариев
#Python Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как выполнить код до и после вызова функции?
Это делается через декораторы - один из самых мощных инструментов Python.
Простой пример декоратора
def my_decorator(func):
def wrapper(*args, **kwargs):
# КОД ДО вызова функции
print("Перед вызовом функции")
# Вызываем исходную функцию
result = func(*args, **kwargs)
# КОД ПОСЛЕ вызова функции
print("После вызова функции")
return result
return wrapper
# Используем декоратор
@my_decorator
def greet(name):
print(f"Hello, {name}!")
greet("John")
# Вывод:
# Перед вызовом функции
# Hello, John!
# После вызова функции
Пример 1: Логирование
import time
from functools import wraps
def log_calls(func):
@wraps(func) # Сохраняет имя функции
def wrapper(*args, **kwargs):
print(f"Вызова функции: {func.__name__}")
print(f"Аргументы: {args}, {kwargs}")
result = func(*args, **kwargs)
print(f"Результат: {result}")
return result
return wrapper
@log_calls
def add(a, b):
return a + b
add(5, 3)
# Вывод:
# Вызова функции: add
# Аргументы: (5, 3), {}
# Результат: 8
Пример 2: Измерение времени
import time
from functools import wraps
def measure_time(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
elapsed = time.time() - start
print(f"{func.__name__} заняла {elapsed:.3f} сек")
return result
return wrapper
@measure_time
def slow_function():
time.sleep(2)
return "Done"
slow_function()
# Вывод:
# slow_function заняла 2.001 сек
Пример 3: Проверка прав доступа
from functools import wraps
def require_admin(func):
@wraps(func)
def wrapper(user, *args, **kwargs):
if not user.is_admin:
raise PermissionError("Нет доступа")
return func(user, *args, **kwargs)
return wrapper
@require_admin
def delete_user(user, user_id):
print(f"Удаляю пользователя {user_id}")
delete_user(admin_user, 123) # OK
delete_user(regular_user, 123) # PermissionError
Пример 4: Кэширование результатов
from functools import wraps
def cache_result(func):
cache = {}
@wraps(func)
def wrapper(*args, **kwargs):
key = (args, tuple(kwargs.items()))
if key in cache:
print(f"Результат из кэша")
return cache[key]
result = func(*args, **kwargs)
cache[key] = result
return result
return wrapper
@cache_result
def expensive_function(n):
print(f"Вычисляю факториал {n}")
return factorial(n)
expensive_function(5) # Вычисляет
# Вывод: Вычисляю факториал 5
expensive_function(5) # Из кэша
# Вывод: Результат из кэша
Пример 5: Обработка исключений
from functools import wraps
def handle_errors(func):
@wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except ValueError as e:
print(f"Ошибка значения: {e}")
return None
except Exception as e:
print(f"Неожиданная ошибка: {e}")
return None
return wrapper
@handle_errors
def divide(a, b):
return a / b
divide(10, 2) # 5.0
divide(10, 0) # Ошибка значения, возвращает None
Декоратор с параметрами
from functools import wraps
def repeat(times):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
results = []
for _ in range(times):
result = func(*args, **kwargs)
results.append(result)
return results
return wrapper
return decorator
@repeat(3)
def hello():
return "Hi"
hello()
# ["Hi", "Hi", "Hi"]
Стек декораторов
@log_calls
@measure_time
@cache_result
def complex_function(n):
return n ** 2
# Декораторы применяются снизу вверх!
# Сначала cache_result, потом measure_time, потом log_calls
В FastAPI
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
def read_item(item_id: int):
return {"item_id": item_id}
# @app.get - это декоратор!
# Он регистрирует функцию как endpoint
С контекстными менеджерами (альтернатива)
from contextlib import contextmanager
@contextmanager
def my_context():
print("Вход")
try:
yield
finally:
print("Выход")
with my_context():
print("Работа")
# Вывод:
# Вход
# Работа
# Выход
Класс-декоратор
class MyDecorator:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print("Перед")
result = self.func(*args, **kwargs)
print("После")
return result
@MyDecorator
def greet(name):
print(f"Hello, {name}")
greet("John")
Итоговый вывод
Для выполнения кода до и после функции используй:
- Декораторы (функции)
- Декораторы (классы)
- Контекстные менеджеры
Декораторы - это мощный инструмент для:
- Логирования
- Измерения времени
- Проверки прав
- Кэширования
- Обработки ошибок
- И многого другого