Python contextmanager () против закрытия (): что подходит для объекта потока?

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

Узнав об этом, я вижу, что есть также функция closing, которая, кажется, работает аналогично, с особым акцентом на закрытие потока по завершении.

Я понимаю, как работает представленная конструкция contextmanager (явно закрывая поток по мере необходимости), но мне интересно, не является ли она неполной - для корректности (и для Pythonic), следует ли также использовать closing или предпочтительнее?

Изменить: тот ответ, на который я ссылался, в настоящее время вызывает fh.close() - мне интересно, должен ли каким-то образом closing быть здесь каким-то образом вместо этого. Документация по contextlib не помогла мне в этом вопросе «или-или-оба», поэтому этот вопрос.


person MartyMacGyver    schedule 25.07.2016    source источник


Ответы (1)


Было бы совершенно неуместно прикреплять contextlib.closing к диспетчеру контекста в этом ответе по многим причинам:

  1. Они не всегда хотят закрыть файл! Этот контекстный менеджер специально разработан для того, чтобы иногда оставлять файл открытым. Это единственная причина, по которой был написан контекстный менеджер.
  2. Когда они хотят закрыть файл, диспетчер контекста уже делает это.
  3. Обертывание closing вокруг контекстного менеджера попытается закрыть неправильный объект.

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

person user2357112 supports Monica    schedule 25.07.2016
comment
Ответ, на который я ссылался, не использует closing, но поскольку он выборочно открывает поток, он также закрывает его при выходе. Я не был уверен, есть ли место для closing в этой конструкции, или closing будет альтернативой. Не похоже, что закрытие здесь имеет место, но я не понимаю, как with узнает, что нужно закрыть соответствующий поток самостоятельно (опять же, учитывая способ построения ответа). Или вы предлагаете with внутри контекстного менеджера? Это даже сработает? - person MartyMacGyver; 25.07.2016
comment
@MartyMacGyver: Тогда вам следует прочитать о что делает contextlib.closing , и, возможно, прочтите исходный PEP для оператора with, чтобы узнать больше о как работает with. with знает, что нужно закрыть поток из-за этой строки fh.close(). - person user2357112 supports Monica; 25.07.2016
comment
Хорошо, я понимаю, о чем ты говоришь. Я думал, вы предлагаете, что fh.close() тоже не нужен. Мне просто интересно, может ли closing быть каким-то образом предпочтительнее fh.close()... и похоже, что это определенно не так. (Именно после прочтения и повторного чтения этих документов я оказался здесь, задав свой первоначальный вопрос... было немного расплывчато, что было предпочтительнее.) - person MartyMacGyver; 25.07.2016