try except inside a with open

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri Jul 20 20:44:05 EDT 2018


On Fri, 20 Jul 2018 23:29:21 +0530, Ganesh Pal wrote:

> Dear python Friends,
> 
> 
> I need a quick suggestion on the below code.
> 
> def modify_various_line(f):
>     """ Try modifiying various line """
>     try:
>         f.write('0123456789abcdef')
>         f.seek(5)     # Go to the 6th byte in the file
>         print f.read(1)
>         f.seek(-3, 2) # Go to the 3rd byte before the end
>         print f.read(1)
>         f.write('END')
>     except IOError as e:
>        raise
>     return True

(1) Since this function always returns True (if it returns at all), what 
is the point? There's no point checking the return result, since it's 
always true, so why bother returning anything?

(2) What's the point of catching an exception only to immediately, and 
always, re-raise it?

It seems to me that your code above is better written like this:

def modify_various_line(f):
    """ Try modifying various line """
    f.write('0123456789abcdef')
    f.seek(5)     # Go to the 6th byte in the file
    print f.read(1)
    f.seek(-3, 2) # Go to the 3rd byte before the end
    print f.read(1)
    f.write('END')



> def h():
>     try:
>         with open('/tmp/file.txt', 'r+') as f:
>              try:
>                  modify_various_line(f)
>              except Exception as e:
>                print e
>     except IOError as e:
>         print(e)

Debugging is hard enough without destroying useful debugging information. 
Tracebacks are not your enemy to be hidden and suppressed (at least not 
during development) but your greatest friend in the world, one who tells 
you the embarrassing errors you have made (bugs) so you can fix them.

https://realpython.com/the-most-diabolical-python-antipattern/


def h():
    with open('/tmp/file.txt', 'r+') as f:
        modify_various_line(f)


is much shorter, easier to read, and if an error occurs, you get the 
benefit of the full traceback not just the abbreviated error message.

Tracebacks are printed to standard error, not standard out, so they can 
be redirected to a log file more easily. Or you can set an error handler 
for your entire application, so that in production any uncaught exception 
can be logged without having to fill your application with boilerplate 
"try...except...print >>sys.stderr, err".

But if you *really* have to catch the exception and suppress the 
traceback, try this:

def h():
    try:
        with open('/tmp/file.txt', 'r+') as f:
            modify_various_line(f)
    except IOError as e:
        print(e)

There's no need to nest two except clauses, both of which do the same 
thing with an exception, and one of which will cover up bugs in your code 
as well as expected failures.



> (1) Can we  use try and expect  in  a 'with open' function as shown in
> the below example code .

Yes.


> (2)  If I hit any other exceptions  say Value-error can I catch them as
> show below

If you hit ValueError, that is almost always a bug in your code. That's 
exactly the sort of thing you *shouldn't* be covering up with an except 
clause unless you really know what you are doing.



-- 
Steven D'Aprano
"Ever since I learned about confirmation bias, I've been seeing
it everywhere." -- Jon Ronson



More information about the Python-list mailing list