Менеджеры контекста
Часть раздела Object Oriented Programming путешествия по Python на Coddy — урок 41 из 64.
Менеджеры контекста позволяют выделять и освобождать ресурсы именно тогда, когда это необходимо. Они обеспечивают правильную очистку даже в случае возникновения ошибок.
Вот самый распространенный пример использования инструкции with:
with open('example.txt', 'w') as file:
file.write('Hello, world!')
# Файл автоматически закрывается здесьФайл автоматически закрывается после завершения блока, даже если возникает исключение.
Создайте свой собственный менеджер контекста, реализовав методы __enter__ и __exit__:
class MyContext:
def __enter__(self):
print("Entering the context")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("Exiting the context")
return False # Не подавлять исключенияИспользуйте свой собственный менеджер контекста:
with MyContext() as ctx:
print("Inside the context")Вывод:
Entering the context
Inside the context
Exiting the contextСоздайте более практичный менеджер контекста для подключений к базе данных:
class DatabaseConnection:
def __init__(self, db_name):
self.db_name = db_name
self.connection = None
def __enter__(self):
print(f"Connecting to {self.db_name}")
self.connection = f"Connection to {self.db_name}"
return self.connection
def __exit__(self, exc_type, exc_val, exc_tb):
print(f"Closing connection to {self.db_name}")
self.connection = None
with DatabaseConnection("users_db") as conn:
print(f"Using {conn}")
print("Performing database operations...")Обработка исключений в контекстных менеджерах:
class SafeContext:
def __enter__(self):
print("Setting up resources")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("Cleaning up resources")
if exc_type:
print(f"An exception occurred: {exc_val}")
return False # Не подавлять исключение
with SafeContext():
print("Working with resources")
# raise ValueError("Something went wrong") # Раскомментируйте для тестированияВывод:
Connecting to users_db
Using Connection to users_db
Performing database operations...
Closing connection to users_db
Setting up resources
Working with resources
Cleaning up resourcesМетод __exit__ принимает три параметра:
exc_type: Тип исключения (или None)exc_val: Значение исключения (или None)exc_tb: Трассировка исключения (или None)
Ключевой момент: Менеджеры контекста используют методы __enter__ и __exit__ для управления ресурсами. Инструкция with автоматически вызывает эти методы, обеспечивая правильную настройку и очистку. Это особенно полезно для файлов, подключений к базам данных и других ресурсов, требующих гарантированной очистки.
Задание
ЛегкоВ этом испытании вам предстоит реализовать класс менеджера контекста, который измеряет время, прошедшее между входом в блок контекста и выходом из него.
timer.py— содержит реализацию классаTimer(это файл, который вы будете редактировать)driver.py— содержит комплексные тестовые случаи (не изменять)
Реализуйте менеджер контекста Timer в timer.py, следуя комментариям TODO. Класс должен:
- Записывать время начала при входе в контекст
- Записывать время окончания при выходе
- Вычислять и отображать прошедшее время
Шпаргалка
Менеджеры контекста выделяют и освобождают ресурсы именно тогда, когда это необходимо, обеспечивая правильную очистку даже в случае возникновения ошибок.
Используйте оператор with для автоматического управления ресурсами:
with open('example.txt', 'w') as file:
file.write('Hello, world!')
# Файл автоматически закрывается здесьСоздавайте пользовательские менеджеры контекста, реализуя методы __enter__ и __exit__:
class MyContext:
def __enter__(self):
print("Entering the context")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("Exiting the context")
return False # Не подавлять исключения
with MyContext() as ctx:
print("Inside the context")Метод __exit__ принимает три параметра:
exc_type: Тип исключения (или None)exc_val: Значение исключения (или None)exc_tb: Трассировка исключения (или None)
Обработка исключений в менеджерах контекста:
class SafeContext:
def __enter__(self):
print("Setting up resources")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("Cleaning up resources")
if exc_type:
print(f"An exception occurred: {exc_val}")
return False # Не подавлять исключениеПопробуйте сами
from timer import Timer
import time
# Обработчик тестовых случаев
test_case = input()
if test_case == "basic_test":
# Тест базовой функциональности
with Timer():
# Симуляция работы
time.sleep(2) # Это заставляет программу ждать 2 секунды
elif test_case == "nested_contexts":
# Тест вложенных контекстных менеджеров
with Timer():
time.sleep(1)
with Timer():
time.sleep(1)
elif test_case == "exception_handling":
# Тест обработки исключений внутри контекста
try:
with Timer():
time.sleep(1)
raise ValueError("Test exception")
except ValueError as e:
print(f"Caught exception: {e}")
elif test_case == "zero_sleep":
# Тест с минимальной задержкой
with Timer():
time.sleep(0.001)
elif test_case == "multiple_timers":
# Тест нескольких таймеров последовательно
with Timer():
time.sleep(1)
with Timer():
time.sleep(0.5)
with Timer():
time.sleep(2)
elif test_case == "as_decorator":
# Тест таймера в контексте функции
def timed_function():
with Timer():
time.sleep(2)
timed_function()
else:
# Тест по умолчанию - базовая функциональность
with Timer():
# Симуляция работы
time.sleep(2) # Это заставляет программу ждать 2 секунды
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Object Oriented Programming
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыПараметр selfМетодыАтрибутыМетод-конструктор (__init__)Повторение — Простой калькулятор4Наследование
Базовое наследованиеФункция super()Переопределение методовМножественное наследованиеПорядок разрешения методовИтоги — Иерархия сотрудников7Специальные методы
Введение в магические методыПерегрузка операторовМагические методы контейнеровПовторение — Пользовательский список10Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн Strategy5Полиморфизм
Снова о переопределении методовУтиная типизацияАбстрактные классы и методыПроектирование интерфейсовИтоги — Калькулятор фигур8Продвинутые концепции ООП
Композиция против наследованияМиксиныСтатические методы и методы классаДекораторы классовМенеджеры контекста11Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн Компоновщик3Свойства классов
Переменные экземпляра и классаДекораторы свойствПриватные атрибутыИтоги — Менеджер банковского счета6Инкапсуляция
Public, Protected, Private члены классаМодификаторы доступаСокрытие данныхДекораторы property: продвинутый уровеньИтоги: Система учета студентов12Проект: Управление библиотекой
Обзор проектаКлассы Book и User