If you're opening a file using the 'with' statement, do you still need to close the file object?
Question:
For opening files, I’m used to the apparently older syntax:
f = open("sub_ranks.txt","r+")
for line in f:
...
f.close()
I’ve been told to use this syntax instead a couple of times now..
with open("sub_ranks.txt", "r+") as f:
for line in f:
...
Is a file object “close” statement still needed in the second example, when the “with” statement is being used?
And if so, is there any concrete reason to use the “with” statement for file reading? In this case, it’s (slightly) more verbose.
Answers:
From the python docs, I see that with is a syntactic sugar for the try/finally blocks.
So,
Is a file object "close" statement still needed in the second example, when the "with" statement is being used?
No.
From the Python docs:
The ‘with‘ statement clarifies code that previously would use
try…finally blocks to ensure that clean-up code is executed. In this
section, I’ll discuss the statement as it will commonly be used. In
the next section, I’ll examine the implementation details and show how
to write objects for use with this statement.
The ‘with‘ statement is a control-flow structure whose basic structure
is:
with expression [as variable]: with-block
The expression is evaluated, and it should result in an object that
supports the context management protocol (that is, has enter() and
exit() methods).
Here‘s another article that makes it clear.
The answer to your immediate question is “No”. The with
block ensures that the file will be closed when control leaves the block, for whatever reason that happens, including exceptions (well, excluding someone yanking the power cord to your computer and some other rare events).
So it’s good practice to use a with
block.
Now arguably, having opened a file only for reading and then failing to close it is not that much of a problem. When garbage collection comes around (whenever that may be), that file will be closed, too, if there are no references to it anymore; at the latest that will happen when your program exits. In fact, several code samples in the official docs neglect closing a file that has been opened only for read access. When writing a file or when using the “read plus” mode like in your example, you definitely need to close the file. There are many questions her on SO dealing with incomplete/corrupted files because of a failure to close them properly.
No.
Say you want to print the hostname like so:
with open("/etc/hostname","r") as f: print f.read()
It will open the file, do its job then close the file.
with
statement is a compact statement that combines the opening of the file and processing of the file along with inbuilt exception handling.
with open(filename,file_mode) as file_object:
#do the manipulation
So with closes the file automatically in both the cases:
- After successful compilation of block
- or If it encounters an error
Note: If you don’t want to use the with
statement then you can always use the try and except
through which you can explicitly handle the exception.
try :
#code you wanna run
except EOFError:
filehandle.close()
For opening files, I’m used to the apparently older syntax:
f = open("sub_ranks.txt","r+")
for line in f:
...
f.close()
I’ve been told to use this syntax instead a couple of times now..
with open("sub_ranks.txt", "r+") as f:
for line in f:
...
Is a file object “close” statement still needed in the second example, when the “with” statement is being used?
And if so, is there any concrete reason to use the “with” statement for file reading? In this case, it’s (slightly) more verbose.
From the python docs, I see that with is a syntactic sugar for the try/finally blocks.
So,
Is a file object "close" statement still needed in the second example, when the "with" statement is being used?
No.
From the Python docs:
The ‘with‘ statement clarifies code that previously would use
try…finally blocks to ensure that clean-up code is executed. In this
section, I’ll discuss the statement as it will commonly be used. In
the next section, I’ll examine the implementation details and show how
to write objects for use with this statement.The ‘with‘ statement is a control-flow structure whose basic structure
is:with expression [as variable]: with-block
The expression is evaluated, and it should result in an object that
supports the context management protocol (that is, has enter() and
exit() methods).
Here‘s another article that makes it clear.
The answer to your immediate question is “No”. The with
block ensures that the file will be closed when control leaves the block, for whatever reason that happens, including exceptions (well, excluding someone yanking the power cord to your computer and some other rare events).
So it’s good practice to use a with
block.
Now arguably, having opened a file only for reading and then failing to close it is not that much of a problem. When garbage collection comes around (whenever that may be), that file will be closed, too, if there are no references to it anymore; at the latest that will happen when your program exits. In fact, several code samples in the official docs neglect closing a file that has been opened only for read access. When writing a file or when using the “read plus” mode like in your example, you definitely need to close the file. There are many questions her on SO dealing with incomplete/corrupted files because of a failure to close them properly.
No.
Say you want to print the hostname like so:
with open("/etc/hostname","r") as f: print f.read()
It will open the file, do its job then close the file.
with
statement is a compact statement that combines the opening of the file and processing of the file along with inbuilt exception handling.
with open(filename,file_mode) as file_object:
#do the manipulation
So with closes the file automatically in both the cases:
- After successful compilation of block
- or If it encounters an error
Note: If you don’t want to use the with
statement then you can always use the try and except
through which you can explicitly handle the exception.
try :
#code you wanna run
except EOFError:
filehandle.close()