How is "c" better than try / catch to open a file in Python?

I realized that the with statement will help you do this:

 try: f = open(my_file) do_stuff_that_fails() except: pass finally: f.close() 

AT:

 with open(my_file) as f: do_stuff_that_fails() 

But how is it better? You still have to handle the case when the file cannot be opened (for example, tell the user to tell him that he does not have permissions), so in fact you would:

 try: with open(my_file) as f: do_stuff_that_fails() except (IOError, OSError, Failure) as e: do_stuff_when_it_doesnt_work() 

Which is equivalent:

 try: f = open(my_file) do_stuff_that_fails() except (IOError, OSError, Faillure) as e: do_stuff_when_it_doesnt_work() finally: f.close() 

Yes, you got two lines, but you added a nesting level that doesn't make reading easier. Is the purpose of the with statement to keep two lines, or am I missing something?

It seems like you need to add a keyword just for this, so I feel there is some syntax to handle the extra attempt / other than the one I don't know about.

+31
python exception with-statement
Jan 08 2018-12-12T00:
source share
3 answers

For starters, this will help prevent the problem that you presented in your try ... finally ... example.

How did you structure it, if an exception is thrown when you try to open a file, you will never associate an open file with the name f , which will either lead to a NameError in the finally clause (if f has never been bound within the scope) or something completely unexpected ( if it is).

The correct structure (equivalent with ):

 f = open(my_file) try: do_stuff_that_fails() finally: f.close() 

(note - there is no need for an except clause if you have nothing to do there).

The second example is similarly incorrect and should be structured as follows:

 try: f = open(my_file) try: do_stuff_that_fails() except EXPECTED_EXCEPTION_TYPES as e: do_stuff_when_it_doesnt_work() finally: f.close() except (IOError, OSError) as e: do_other_stuff_when_it_we_have_file_IO_problems() 

The second (as indicated in another answer) is that you cannot forget to call f.close() .

BTW, the term "context management" rather than "resource management" - the with statement manages contexts, some of which may be resources, while others may not. For example, it is also used with decimal to create a decimal context for a specific block of code.

Finally (in response to your comment on the previous answer), you should never rely on refcount semantics to handle resources in Python. Jython, IronPython, and PyPy have non-refcount semantics, and nothing prevents CPython from going the other way (although this is unlikely for the near future). In a tight loop (for example, os.walk ) it is very easy to run out of file descriptors if the code based on refcount semantics runs on a virtual machine with different behavior.

+28
Jan 08 '12 at 2:50
source share

In the example you give, this is not better. It is best to catch exceptions as close to the point at which they are thrown to avoid unbound exceptions of the same type.

 try: file = open(...) except OpenErrors...: # handle open exceptions else: try: # do stuff with file finally: file.close() 

As with this, the with statement does not allow you to exclude exceptions that have occurred during its evaluation. It has been suggested to add exception handling to this list on the mailing list:

 with open(...) as file: # do stuff with file except OpenErrors...: # handle open exceptions 

But it was hit .

Finally, it is worth noting that you can directly enter and exit context managers:

 file = open(...).__enter__() file.__exit__(typ, val, tb) 

This is described in more detail here and here .

As a general guide, with statements are superior to cases where exceptions are not expected, and the default input / open / acquire behavior is adequate. Examples include required files and simple locking.

+15
Jan 08 '12 at 3:17
source share

This is for resource management ... not for how you react to an exception otherwise :)

Cannot forget f.close() when using with . Thus, it performs the same role as using in C #.

Happy coding.

+6
Jan 08 2018-12-12T00:
source share



All Articles