try except inside a with open
Cameron Simpson
cs at cskk.id.au
Sat Jul 21 06:18:11 EDT 2018
Please try to preserve the attribution lines of previous authors. The inner
quote below comes from Steven D'Aprano.
On 21Jul2018 15:13, Ganesh Pal <ganesh1pal at gmail.com> wrote:
>> (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?
>
>If I don't return anything from a function it returns None. But would it
>be better if for the function i.e modify_various_line(f) to atleast catch
>or handle exceptions and log it for debugging purpose
Usually not.
Problems with this approach (catches and logging, and _concealing_ the
exception from the caller) include:
1: the primary one is: if you do this, the caller will never know that anything
went wrong
2: there isn't necessarily any logging setup anyway - small function should not
need to know or care, otherwise they're hard to test and may make a lot of
unwanted noise
Most functions do not know the larger programme context - it is therefore not
possible to decide how to handle all exceptions. So unless the exception is
anticipated for some specific situation, it is better to let it excape for the
caller to handle (or not).
Look at your example function:
>Example:
>
>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:
> logging.error("Error: got %s" , % (str(e)))
This function returns None regardless of success or failure. Generally for a
function like this, which doesn't return a "result", you want it to return on
success and raise an exception on failure. In that way, the caller can presume
things are good if no exception occurred.
Here you print an error message to the log and return None anyway.
Firstly, your error message has no context: there's just an IOError in the log,
so nobody can review the log and know what the error is associate with. If the
IOError had been allowed to get out, the caller could have responded
appropriately (or not, letting the exception further out to someone who can, or
aborting the programme if nobody deals with it). This isn't as bad as it
sounds; that abort is a symptom of a genuinely unanticipated error, which
should be either understood properly and handled, or the invoker of the program
should respond to its termination. In a sense, your whole programme is itself a
function - if it didn't work, the person invoking it needs to find out.
Secondly, because you catch the error, the caller has no way to know the
function did not accomplish what the caller expected. That is "silent failure",
and generally a bad thing.
Consider this trite function:
def get_colour(thing, default='black'):
try:
colour = thing.colour
except AttributeError:
colour = default
return colour
Here we handle the case where a thing has no .colour attribute and return a
default. The function is designed for this, and has scope for the caller to
specify the default.
The general rule in Python is: only catch an exception if you know exactly what
to do with it, and your function will complete with a _correct_ result if you
do it.
Conversely, _don't_ try to handle any other situation. (This makes your task
easier, too!)
Here's an example:
import errno
...
# clean up a file...
try:
os.remove(filename)
except OSError as e:
if e.errno == errno.ENOENT:
# it is ok if the file is already gone
pass
else:
raise
Here we're catching all OSErrors, but only handling the specific situation we
understand (the file doesn't exist, and in this case that is possible and
normal). If there was any other kind of OSError (eg a permission error or
anything else really - it is all unknown), we reraise the original exception.
There are any number of reasons that things can go wrong, including the code
_calling_ your function asking for the wrong thing. Letting the exception out
lets these situations get debugged.
Cheers,
Cameron Simpson <cs at cskk.id.au>
More information about the Python-list
mailing list