Что такое контекстный менеджер в Python и как он используется в DevOps-скриптах?

«Что такое контекстный менеджер в Python и как он используется в DevOps-скриптах?» — вопрос из категории Скриптинг и автоматизация, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В DevOps-скриптах на Python контекстный менеджер — это инструмент для безопасного управления ресурсами (сетевыми соединениями, файлами, временными каталогами). Он гарантирует, что ресурсы будут корректно выделены и, что критически важно, освобождены (закрыты, удалены) даже при возникновении ошибки.

Контекстный менеджер реализует методы __enter__() (выполняется при входе в блок with) и __exit__() (выполняется при выходе).

Практические примеры из DevOps:

  1. Работа с временными файлами (модуль tempfile):

    import tempfile
    import os
    
    # Создание и автоматическое удаление временного каталога
    with tempfile.TemporaryDirectory() as tmpdir:
        config_path = os.path.join(tmpdir, 'config.yaml')
        with open(config_path, 'w') as f:
            f.write('server: 192.168.1.1')
        # Здесь можно работать с файлом
        print(f"Config created at: {config_path}")
    # При выходе из блока `with` каталог `tmpdir` и все файлы в нем удаляются
  2. Безопасное изменение текущего рабочего каталога:

    from contextlib import contextmanager
    import os
    
    @contextmanager
    def change_dir(destination):
        """Контекстный менеджер для временной смены рабочей директории."""
        origin = os.getcwd()
        try:
            os.chdir(destination)
            yield  # Выполнение кода внутри блока `with` происходит здесь
        finally:
            os.chdir(origin)  # Всегда возвращаемся в исходную директорию
    
    # Использование
    with change_dir('/var/log'):
        # Выполняем операции в /var/log
        for file in os.listdir('.'):
            print(file)
    # Теперь мы снова в исходной директории

Использование with для работы с файлами, сетевыми сессиями (requests.Session()) или блокировками делает скрипты надежнее и чище.