Discussion:
[Tutor] general exception questions
richard kappler
2015-10-05 17:46:52 UTC
Permalink
I'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?

EX:

for line in file:
try:
do something
except:
pass

I know (so many of you have told me :-) that using pass is a bad idea, but
how else do you skip the current line if the 'try' can't be done, and go on
to the next line exiting the program with a trace error?

regards, Richard
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Alan Gauld
2015-10-05 18:11:27 UTC
Permalink
Post by richard kappler
I'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, in your example it would ignore the exception and just move on to
the next line. Using continue would do the same and be more explicit.
If you do want to stop the loop use break.
Post by richard kappler
do something
pass
I know (so many of you have told me :-) that using pass is a bad idea,
Not necessarily, pass is fine in many situations.
The only problem is in situations where it's not
needed at all - then its better to just simplify
the construct. For example:

if some_test():
do_something()
else:
pass

is better written as just

if some_test():
do_something()

But something like:

class MyNewException(Exception): pass

is absolutely OK.
Post by richard kappler
how else do you skip the current line if the 'try' can't be done, and go on
to the next line exiting the program with a trace error?
That last sentence confused me. If you use pass (or continue)
you will NOT get any trace error. If you want to store the
error to report it at the end then it's quite a bit more work,
you would need something like:

errors = []
for line in file:
try:
process(line)
except SomeError as e:
errors.append((line,e))

if errors:
for e in errors:
display_error(e)

where display_error() is an exercise for the student :-)

hth
--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
richard kappler
2015-10-05 18:23:39 UTC
Permalink
Post by richard kappler
how else do you skip the current line if the 'try' can't be done, and go on
Post by richard kappler
to the next line exiting the program with a trace error?
That last sentence confused me. If you use pass (or continue)
you will NOT get any trace error. If you want to store the
error to report it at the end then it's quite a bit more work,
Yup, confused myself when I reread it, sorry Alan. It should have been ..if
the 'try' can't be done, and go on to the next line INSTEAD OF exiting the
program with a trace error.
Post by richard kappler
errors = []
process(line)
errors.append((line,e))
display_error(e)
where display_error() is an exercise for the student :-)
Interesting. Sounds like something else I need to take a round turn on.

regards, Richard
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Mark Lawrence
2015-10-05 21:39:13 UTC
Permalink
Post by richard kappler
I'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?
do something
pass
I know (so many of you have told me :-) that using pass is a bad idea, but
how else do you skip the current line if the 'try' can't be done, and go on
to the next line exiting the program with a trace error?
regards, Richard
Don't put the `try: except:` there in the first place. This is the best
way to approach development. Let Python throw all your programming
errors at you, then refine your code to catch the ones you need to. See
https://docs.python.org/3/library/exceptions.html#exception-hierarchy
for the ones you would potentially need to catch for file handling under
OSError.

One must also add the obligatory never use a bare `except:`
--
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Laura Creighton
2015-10-05 22:13:06 UTC
Permalink
Post by Mark Lawrence
Post by richard kappler
I'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?
do something
pass
I know (so many of you have told me :-) that using pass is a bad idea, but
how else do you skip the current line if the 'try' can't be done, and go on
to the next line exiting the program with a trace error?
regards, Richard
Don't put the `try: except:` there in the first place. This is the best
way to approach development. Let Python throw all your programming
errors at you, then refine your code to catch the ones you need to. See
https://docs.python.org/3/library/exceptions.html#exception-hierarchy
for the ones you would potentially need to catch for file handling under
OSError.
One must also add the obligatory never use a bare `except:`
--
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.
Mark Lawrence
I think this depends on what the script is doing. For commerical,
production use you generally want to find out what the errors are
and do something reasonable for them -- but for my own use there are
plenty of times when

I want to run this thing once.
If it runs into trouble I want it to keep on trying to do its thing.
The only thing I might consider doing with any exceptions that get
raised is logging them before ignoring them.
The worst thing that could happen is for the script to quit running
after a few hours because some wretched exception I wasn't ready for
happened. This means I will have to add that exception to the list of
things to ignore and run the thing again next night ...

Laura


_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Steven D'Aprano
2015-10-06 01:29:24 UTC
Permalink
Post by richard kappler
I'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 kappler
do 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
Continue reading on narkive:
Loading...