Brian D wrote:
On Dec 30, 11:06 am, samwyse <samw...@gmail.com> wrote:
On Dec 30, 10:00 am, Brian D <brianden...@gmail.com> wrote:

What I don't understand is how to test for a valid URL request, and
then jump out of the "while True" loop to proceed to another line of
code below the loop. There's probably faulty logic in this approach. I
imagine I should wrap the URL request in a function, and perhaps store
the response as a global variable.
This is really more of a basic Python logic question than it is a
urllib2 question.
There, I've condensed your question to what you really meant to say.
You have several approaches.  First, let's define some useful objects:>>> 
max_attempts = 5
def do_something(i):
        assert 2 < i < 5

Getting back to original question, if you want to limit the number of
attempts, don't use a while, use this:

for count in xrange(max_attempts):
        print 'attempt', count+1
        do_something(count+1)

attempt 1
Traceback (most recent call last):
  File "<pyshell#55>", line 3, in <module>
    do_something(count+1)
  File "<pyshell#47>", line 2, in do_something
    assert 2 < i < 5
AssertionError

If you want to keep exceptions from ending the loop prematurely, you
add this:

for count in xrange(max_attempts):
        print 'attempt', count+1
        try:
                do_something(count+1)
        except StandardError:
                pass

Note that bare except clauses are *evil* and should be avoided.  Most
exceptions derive from StandardError, so trap that if you want to
catch errors.  Finally, to stop iterating when the errors cease, do
this:

try:
        for count in xrange(max_attempts):
                print 'attempt', count+1
                try:
                        do_something(count+1)
                        raise StopIteration
                except StandardError:
                        pass
except StopIteration:
        pass

attempt 1
attempt 2
attempt 3

Note that StopIteration doesn't derive from StandardError, because
it's not an error, it's a notification.  So, throw it if and when you
want to stop iterating.

BTW, note that you don't have to wrap your code in a function.
do_something could be replaced with it's body and everything would
still work.

I'm totally impressed. I love elegant code. Could you tell I was
trained as a VB programmer? I think I can still be reformed.

I appreciate the admonition not to use bare except clauses. I will
avoid that in the future.

I've never seen StopIteration used -- and certainly not used in
combination with a try/except pair. That was an exceptionally valuable
lesson.

I think I can take it from here, so I'll just say thank you, Sam, for
steering me straight -- very nice.

Instead of raising StopIteration you could use 'break':

for count in xrange(max_attempts):
    print 'attempt', count + 1
    try:
        do_something(count + 1)
        break
    except StandardError:
        pass

The advantage, apart from the length, is that you can then add the
'else' clause to the 'for' loop, which will be run if it _didn't_ break
out of the loop. If you break out only after do_something() is
successful, then not breaking out means that do_something() never
succeeded:

for count in xrange(max_attempts):
    print 'attempt', count + 1
    try:
        do_something(count + 1)
        break
    except StandardError:
        pass
else:
    print 'all attempts failed'
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to