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

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to