Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #196413

Re: Best use of "open" context manager

From Rob Cliffe <rob.cliffe@btinternet.com>
Newsgroups comp.lang.python
Subject Re: Best use of "open" context manager
Date 2024-07-06 14:27 +0100
Message-ID <mailman.24.1720481658.2981.python-list@python.org> (permalink)
References <954c4ca8-cf37-4482-a1be-46d39cb503f9@btinternet.com> <CAHVvXxSKiws7R9v_3z9_8TP-Zsbw9MaXsNKxThLP4odWAcTUCA@mail.gmail.com> <74a41289-d62f-465f-a5ac-665843c03528@btinternet.com>

Show all headers | View raw



On 06/07/2024 12:57, Oscar Benjamin via Python-list wrote:
> On Sat, 6 Jul 2024 at 11:55, Rob Cliffe via Python-list
> <python-list@python.org> wrote:
>> Consider this scenario (which I ran into in real life):
>>       I want to open a text file and do a lot of processing on the lines
>> of that file.
>>       If the file does not exist I want to take appropriate action, e.g.
>> print an error message and abort the program.
>> I might write it like this:
>>
>> try:
>>       with open(FileName) as f:
>>           for ln in f:
>>               print("I do a lot of processing here")
>>               # Many lines of code here .....
>> except FileNotFoundError:
>>       print(f"File {FileName} not found")
>>       sys.exit()
>>
>> but this violates the principle that a "try" suite should be kept small,
>> so that only targeted exceptions are trapped,
>> not to mention that having "try" and "except" far apart decreases
>> readability.
> This is catching a targeted exception (FileNotFoundError) so I think
> it is fine. If the intention is just to call sys.exit() on error then
> I wouldn't worry too much about having too much code in the try. Just
> make sure that you do this in any other place where you open a file as
> well.
>
> One possible improvement is that you could catch the exception and use
> its filename attribute:
>
> except FileNotFoundError as e
>       print(f"File {e.filename} not found")
>
> That way if you did catch the wrong FileNotFoundError then at least
> you print the correct filename.
Good point, Oscar - thank you.  (Even if you did omit the colon on the 
"except" line🙂.  I've often thought we should have "Python without 
colons" as this is a mistake I frequently make.)
>
> Alternatively:
>
> except FileNotFoundError as e
>       if e.filename != FileName:
>            raise  # re-raise if not the intended exception
>       print(f"File {e.filename} not found")
Indeed, that covers all basis.
> For readability I would just move the many lines of code into a
> separate function.
That may not always be convenient (e.g. if the many-lines-of-code needs 
to access a lot of local variables) but fair enough.
Thanks for your answer.
Rob Cliffe
>
> The reason to avoid having too much code in the try mainly applies to
> situations where you are going to do something other than call
> sys.exit() and the exception is overly generic like ValueError or
> TypeError. If the exception can easily be raised by a bug or something
> other than the intended cause then it is bad to catch exceptions
> around a larger block of code.
>
> If it is expected that the caller of a function might have good reason
> to catch the exception and handle it somehow then it is better to make
> a dedicated exception class and raise that instead. When there is only
> one place in the code that raises a particular exception type and only
> one place that catches it then it is usually going to be clear that
> you are catching the expected exception.
>
> --
> Oscar

Back to comp.lang.python | Previous | Next | Find similar | Unroll thread


Thread

Re: Best use of "open" context manager Rob Cliffe <rob.cliffe@btinternet.com> - 2024-07-06 14:27 +0100

csiph-web