Why is `with open()` better for opening files in Python?

喜你入骨 提交于 2019-11-28 03:46:46

问题


Frequently when someone posts their code, people will add as an aside that "you should use with open('filename') as f syntax now." I agree that most of the old-fashioned f = open() statements don't have an accompanying .close(), and I have even answered questions where this reliance on "implicit close" was the entire cause of their programming problem.

However, in some cases nesting your code inside the with block seems to create other inconveniences in writing the code. For example I sometimes like to use a flag at the beginning to say writefile = True. This lets me only open and close the file if it is going to be used, while keeping the same processing thread. At various places in the code I can either print to screen or write to a file. (I realize I would open stdout or the file at the beginning and use that approach instead.)

My question is: besides not having to explicitly close the file, are there other reasons to use the with syntax for handling files, especially output files? ("More pythonic" by itself is not a reason.) If this is a duplicate, I would be glad to have this pointed out, but I couldn't find it myself.


回答1:


There's no other advantage of with: ensuring cleanup is the only thing it's for.

You need a scoped block anyway in order to close the file in the event of an exception:

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

So, the thing you describe as a disadvantage of with is really a disadvantage of correct code (in the case where cleanup is required), no matter how you write it.




回答2:


We want that guarantee that some cleanup/finalization takes place. That is the use of with.

Yes, most commonly, we would like to close a file, but you could come up with other examples.

PEP 343 has a non-file example:

A template for ensuring that a lock, acquired at the start of a block, is released when the block is left:

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

Used as follows:

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).



回答3:


besides not having to explicitly close the file, are there other reasons to use the with syntax for handling files

I think the main reason for using ContextManager during file open is idea that this file will be open in any case whether everything is ok or any exception is raised.

it Is analog for following statement

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



回答4:


For example I sometimes like to use a flag at the beginning to say writefile = True. This lets me only open and close the file if it is going to be used, while keeping the same processing thread. At various places in the code I can either print to screen or write to a file. (I realize I would open stdout or the file at the beginning and use that approach instead.)

This describes code with a lot of duplicative if statements.

besides not having to explicitly close the file, are there other reasons to use the with syntax for handling files, especially output files?

It eliminates the need to write your own finally blocks, and it structures your code such that you avoid duplicative if statements, and it allows readers to easily locate the place where a file object (or rather variable holding a file object) is defined.

So instead of your mess of flags, you can do:

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


来源:https://stackoverflow.com/questions/19711344/why-is-with-open-better-for-opening-files-in-python

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!