Почему `with open () ' лучше для открытия файлов в Python?

часто, когда кто-то публикует свой код, люди добавят, что "вы должны использовать with open('filename') as f синтаксис сейчас.- Я согласен, что большинство старомодных ... --1--> заявления не имеют сопроводительные .close(), и я даже ответил на вопросы, где эта зависимость от" неявного закрытия " была всей причиной их проблемы программирования.

однако в некоторых случаях вложенность вашего кода внутри with блок, похоже, создает другие неудобства при написании кода. Для пример мне иногда нравится использовать флаг в начале, чтобы сказать writefile = True. Это позволяет мне открывать и закрывать файл, только если он будет использоваться, сохраняя при этом тот же поток обработки. В разных местах кода я могу либо распечатать на экран, либо записать в файл. (Я понимаю, что открою stdout или файл в начале и вместо этого используйте этот подход.)

мой вопрос: помимо того, что не нужно явно закрывать файл, есть ли другие причины использовать with синтаксис для обработки файлов, особенно выходные файлы? ("Более питонический" сам по себе не является причиной.) Если это дубликат, я был бы рад, чтобы это было указано, но я не мог найти его сам.

4 ответов


нет никакого другого преимущества with: обеспечение очистки только для.

вам все равно нужен блок с областью видимости, чтобы закрыть файл в случае исключения:

writefile = random.choice([True, False])
f = open(filename) if writefile else None
try:
    # some code or other
finally:
    if writefile:
        f.close()

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


мы хотим, чтобы гарантировать, что некоторая очистка/завершение происходит. Это использование with.

Да, чаще всего мы хотели бы закрыть файл, но вы можете придумать другие примеры.

PEP 343 не файл, например:

шаблон для сделать замок приобрел в начале блока, освобождается, когда блок остается:

@contextmanager
def locked(lock):
    lock.acquire()
    try:
        yield
    finally:
        lock.release()

использовать следующим образом:

with locked(myLock):
    # Code here executes with myLock held.  The lock is
    # guaranteed to be released when the block is left (even
    # if via return or by an uncaught exception).

помимо того, что не нужно явно закрывать файл, есть ли другие причины использовать синтаксис with для обработки файлов

Я думаю, что основная причина использования ContextManager во время открытия файла идея, что этот файл будет открыт в любом случае, все ли в порядке или любое исключение возникает.

это аналог для следующего утверждения

f = open(filename, 'w')
try:
    pass
finally:
    f.close()

например, мне иногда нравится использовать флаг в начале, чтобы сказать writefile = True. Это позволяет мне открывать и закрывать файл, только если он будет использоваться, сохраняя при этом тот же поток обработки. В разных местах кода я могу либо распечатать на экран, либо записать в файл. (Я понимаю, что открыл бы stdout или файл в начале и вместо этого использовал бы этот подход.)

это описывает код с большим количеством дублирующих операторов if.

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

это устраняет необходимость писать свой собственный finally блоки, и он структурирует ваш код таким образом, что вы избегаете дублирующих операторов if, и это позволяет читателям легко найти место, где определен файловый объект (или, скорее, переменная, содержащая файловый объект).

Так вместо вашего беспорядка флагов, вы можете do:

with (open('file') if condition else io.BufferedWriter(sys.stdout)) as f:
     pass