Шаг 13.
Python: тонкости программирования. Шаблоны для чистого Python. Менеджеры контекста и инструкция with (общие сведения)

    На этом шаге мы рассмотрим назначение инструкции with.

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

    Итак, в чем же прелесть инструкции with? Она помогает упростить некоторые распространенные шаблоны управления ресурсами, абстрагируясь от их функциональности и позволяя выделять их и использовать повторно.

    Один из хороших способов увидеть эффективное применение данного функционального средства языка - посмотреть на примеры в стандартной библиотеке Python. Встроенная функция open() предоставляет превосходный вариант ее применения:

with open('hello.txt', 'w') as f: 
    f.write('Привет, мир!')

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

f = open('hello.txt', 'w') 
try:
    f.write('Привет, мир!') 
finally:
    f.close()

    Вы сразу можете сказать, что он довольно многословен. Обратите внимание: инструкция try...finally имеет важное значение. Просто написать что-то типа этого было бы недостаточно:

f = open('hello.txt', 'w') 
f.write('Привет, мир!') 
f.close()

    Если во время вызова f.write() случится исключение, то такая реализация не будет гарантировать, что файл будет закрыт, и поэтому наша программа может допустить утечку дескриптора файла. Вот почему инструкция with имеет столь важное значение. Она превращает надлежащее получение и высвобождение ресурсов в пустяковую работу.

    Еще одним хорошим примером, где инструкция with эффективно используется в стандартной библиотеке Python, является класс threading.Lock:

some_lock = threading.Lock()
#  Вредно:
some_lock.acquire()
try:
    #  Сделать что-то... 
finally:
    some_lock.release()

#  Лучше:
with some_lock:
    #  Сделать что-то...

    В обоих случаях использование инструкции with позволяет абстрагироваться от большей части логики обработки ресурса. Вместо необходимости всякий раз писать явную инструкцию try...finally, инструкция with выполняет эту работу за нас.

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

    На следующем шаге мы рассмотрим поддержку инструкции with в собственных объектах.




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