Post by richard kapplerI'm reading up on exception handling, and am a little confused. If you have
an exception that just has 'pass' in it, for example in a 'for line in
file:' iteration, what happens? Does the program just go to the next line?
Yes. The exception is caught and then processing continues in the usual
manner from the except clause. In your example below, that would mean
returning to the start of the for-loop.
Post by richard kapplerdo something
pass
I know (so many of you have told me :-) that using pass is a bad idea
*scratches head*
I don't remember anyone saying that *pass* itself if a bad idea. On it's
own, pass just tells the Python compiler to do nothing.
But what *really is* a bad idea is the bare "except" sitting there like
a land mine, waiting to blow up in your face. Bare excepts have their
uses, their *very rare* uses, but in general what they mostly do is hide
bugs and make them much harder to fix.
https://realpython.com/blog/python/the-most-diabolical-python-antipattern/
What *may* be a bad idea is the "do something" inside a try clause --
it's hard to tell, without knowing what "do something" actually is.
try...except blocks are great, they are an extremely powerful and useful
part of the Python programming language. But they are easy to misuse.
Here are two simple rules for effectively and safely using try...except:
(1) Put the *least amount of code possible* inside the try.
(2) Catch the *fewest number of exceptions* possible in the except.
If you remember those two rules, your try...except blocks will be much
less likely to bite.
You should protect the least amount of code as you can inside the try.
For example, this is probably a bad idea:
try:
i = mylist.index("<tag>")
del other[i + START]
process(mylist)
except ValueError:
# tag not found
handle_missing_tag()
The *intention* is to catch the ValueError that is raised by index()
when "<tag>" is not found, but in fact there are four different
places where ValueError could, potentially, be raised:
- the call to index()
- the calculation of i + START
- the del start[...]
- the function call process(...)
Only in the first case is ValueError expected, and can be safely caught
and handled. In the other three places, a ValueError would be totally
unexpected, and would indicate a bug that needs to be fixed. To fix the
bug, you would need to see it in the first case, and you can't see it
if it is caught and suppressed by the try...except.
This would probably be better written like this:
try:
i = mylist.index("<tag>")
except ValueError:
# tag not found
handle_missing_tag()
else:
del other[i + START]
process(mylist)
or similar. Inside a function, you might do this:
def func():
try:
i = mylist.index("<tag>")
except ValueError:
# tag not found
handle_missing_tag()
return
del other[i + START]
process(mylist)
Now, if process() raises ValueError, you will see it, and can fix the
bug.
Of course, there are times where being lazy is a virtue:
for x in sequence:
try:
process(x)
except Exception:
pass
is fine in the interactive interpreter, where you don't care about best
practices, reliability, long-term maintainability, etc. You don't really
care what goes wrong, you just want to keep going no matter what. But
notice that I've caught Exception, rather than a bare except. I've done
that so that I can interrupt the script and cancel processing with
Ctrl-C, otherwise the KeyboardInterrupt exception will be caught and
ignored too!
But even in this case, the quick-n-dirtiest of the quick-n-dirty
scripts, there's a significant risk of failure:
for x in sequence:
try:
proces(x) # Oops, typo.
except Exception:
pass
I have done this: intending to process a long list, I fired off the
script, then came back an hour or two later only to discover that it had
done *absolutely nothing* due to a silly typo.
--
Steve
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor