Anyway, after open it is a considered best practice to close the file and examples above did not include this. Share improve this answer edited Mar 30 '16 at 17:45. Mar 29, 2016 I think os.path.isfile is better if you just want to 'check' if a file exists since you do not need to actually open the file. Anyway, after open it is a considered best practice to close the file and examples above did not include this.
I got that the with
statement help you to turn this:
Into:
But how is that better? You still got to handle the case with the file not being able to be opened (like prompting the user to tell him he doesn't have permissions), so in reality you'd have:
Which is equivalent to:
Yes, you gained two lines, but you added a level of nesting wich doesn't make it easier to read. Is the purpose of the with
statement to save you two lines or am I missing something?
It seems a lot to add a keyword just for that, so I feel like there is some syntaxe to handle the additional try/except that I don't know about.
skaffman3 Answers
For a start, it helps prevent the problem you've introduced in your try ... finally ...
example.
The way you've structured it, if an exception is thrown while trying to open the file then you will never bind an open file to the name f
, leading to either a NameError
in the finally
clause (if f
has never been bound within scope) or something entirely unexpected (if it has).
The correct structure (equivalent to the with
) is:
(note - no need for an except
clause if you've got nothing to do there).
Your second example similarly is wrong, and should be structured like:
The second is (as stated in another answer) that you can't forget to call f.close()
.
BTW, the term is 'context management', not 'resource management' - the with
statement manages contexts, some of which may be resources, but others not. For example, it's also used with decimal
to establish a decimal context for a particular block of code.
Finally (responding to your comment to the previous answer) you should never rely on refcount semantics for handling resources in Python. Jython, IronPython and PyPy all have non-refcount semantics, and there's nothing preventing CPython from going the other way (though it's highly unlikely for the immediate future). In a tight loop (e.g. os.walk
) it is very very easy to run out of file handles if code relying on refcount semantics is run on a VM with different behaviour.
In the example you give, it's not better. It's best practice to catch exceptions as close to the point they're thrown to avoid catching unrelated exceptions of the same type.
As unfortunately verbose as this is, the with
statement doesn't allow you to catch exceptions thrown during its evaluation. There was a suggestion to add exception handling to this effect on the mailing list:
But this was shot down.
Finally it's worth noting that you can directly enter and exit context managers like so:
This is described in more detail here and here.
As a general guideline, with
statements excel for cases where exceptions are not expected, and the default 'enter/open/acquire' behaviour is adequate. Examples include required files, and simple locking.
It is for resource management ... not for how you react to an exception otherwise :)
There is no way to 'forget' f.close()
when using with
. In this manner it serves the same role as using
in C#.
Happy coding.
Not the answer you're looking for? Browse other questions tagged pythonexceptionwith-statement or ask your own question.
I want to read a .csv file in python.
- I don't know if the file exists.
- My current solution is below. It feels sloppy to me because the two separate exception tests are awkwardly juxtaposed.
Is there prettier way to do it?
Charles HolbrowCharles Holbrow4 Answers
I guess I misunderstood what was being asked. Re-re-reading, it looks like Tim's answer is what you want. Let me just add this, however: if you want to catch an exception from open
, then open
has to be wrapped in a try
. If the call to open
is in the header of a with
, then the with
has to be in a try
to catch the exception. There's no way around that.
So the answer is either: 'Tim's way' or 'No, you're doing it correctly.'.
Previous unhelpful answer to which all the comments refer:
Josh CaswellJosh CaswellHere is a read/write example. The with statements insure the close() statement will be called by the file object regardless of whether an exception is thrown. http://effbot.org/zone/python-with-statement.htm
Adding to @Josh's example;
This way you can attempt to open the file, but if it doesn't exist (if it raises an IOError), alert the user!
Zac BrownZac Brown