Шаг 15.
Python: тонкости программирования. Шаблоны для чистого Python. Менеджеры контекста и инструкция with. Написание красивых API с менеджерами контекста

    На этом шаге мы рассмотрим небольшую реализацию такого API.

    Менеджеры контекста обладают достаточной гибкостью, и если к применению инструкции with подойти творчески, то для своих модулей и классов вы сможете определять удобные API.

    Например, что, если "ресурсом", которым мы хотели бы управлять, являются уровни отступа текста в некоей программе - генераторе отчетов? Что, если бы для этого мы смогли написать исходный код, который выглядит вот так:

with Indenter() as indent: 
    indent.print('привет!') 
    with indent:
        indent.print('здорово') 
        with indent:
            indent.print('бонжур')
    indent.print('эй')

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

привет!
 здорово
  бонжур
эй

    Итак, каким образом вы реализовали бы менеджер контекста, который поддерживал бы эту функциональность?

    Между прочим, для вас это может быть прекрасным упражнением, чтобы понять, как именно работают менеджеры контекста. Поэтому перед тем, как вы обратитесь к моей реализации, приведенной ниже, возьмите паузу и попробуйте реализовать это самостоятельно в качестве задания.

    Если вы готовы взглянуть на реализацию, то ниже показано, как можно воплотить эту функциональность, использовав менеджер контекста на основе класса:

class Indenter:
    def __init__(self):
        self.level = 0

    def __enter__(self):
        self.level += 1 
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.level -= 1

    def print(self, text):
        print(' ' * self.level + text)
Архив с файлом можно взять здесь.

    Неплохо, правда? Надеюсь, что сейчас вы чувствуете себя увереннее при использовании менеджеров контекста Python и инструкции with в собственных программах. Это превосходное функциональное средство языка, позволяющее решать задачи по управлению ресурсами в гораздо более питоновском и удобном в сопровождении стиле.

    Если вы ищете другое упражнение, чтобы понять тему глубже, то попробуйте реализовать менеджер контекста, измеряющий время исполнения блока программного кода с использованием функции time.time. Обязательно напишите его в двух вариантах: на основе декоратора и на основе класса, чтобы усвоить разницу между ними.

    На следующем шаге мы подведем краткие итоги.




Предыдущий шаг Содержание