As a newbie, it's pretty likely that there's a smarter way to do this,
so I'd like to check with the experts:
I need to try calling a function 5 times. If successful, move on; If
not, print an error message, and exit the program:
=====
success = None
for i in range(5):
#Try to fetch public IP
success = CheckIP()
if success:
break
if not success:
print "Exiting."
sys.exit()
=====
Thank you.
Though a bit of an abuse, you can use
if not any(CheckIP() for _ in range(5)):
print "Exiting"
sys.exit()
(this assumes Python2.5, but the any() function is easily
recreated per the docs at [1]; and also assumes the generator
creation of 2.4, so this isn't as useful in 2.3 and below)
Alternatively, you can use the for/else structure:
for i in range(5):
if CheckIP():
break
else:
print "Exiting"
sys.exit()
-tkc
[1]
http://www.python.org/doc/2.5.2/lib/built-in-funcs.html#l2h-10
.
for i in range(5):
if CheckIP():
break
else:
print "Exiting."
sys.exit()
Note very carefully that the "else" goes with the "for" and not the "if".
--
\S -- si...@chiark.greenend.org.uk -- http://www.chaos.org.uk/~sion/
"Frankly I have no feelings towards penguins one way or the other"
-- Arthur C. Clarke
her nu becomeþ se bera eadward ofdun hlæddre heafdes bæce bump bump bump
A little simpler:
for i in range(5):
if CheckIP():
break
else:
print "Exiting."
sys.exit()
The else part will only fire if the for finishes without breaking.
Hope this helps a bit...
Nick Fabry
> Thank you.
> --
> http://mail.python.org/mailman/listinfo/python-list
Thanks guys.
And if you end up doing this for several different functions, you can
factor it out with the following decorator:
class MaxRetriesExceededError(Exception):
pass
def retry(n):
def decorator(f):
def wrapper(*args, **kwds):
for i in xrange(n):
r = f(*args, **kwds)
if r: return r
raise MaxRetriesExceededError
return wrapper
return decorator
If the number of retries is fixed and known at "compile" time, you can
use the standard decorator syntax:
@retry(5)
def CheckIP():
...
If not, just decorate it explicitly at runtime:
def CheckIP():
...
n = int(raw_input('Give number of retries:'))
CheckIP = retry(n)(CheckIP)
HTH,
George
>> success = None
>> for i in range(5):
>> #Try to fetch public IP
>> success = CheckIP()
>> if success:
>> break
>> if not success:
>> print "Exiting."
>> sys.exit()
>
> Though a bit of an abuse, you can use
>
> if not any(CheckIP() for _ in range(5)):
> print "Exiting"
> sys.exit()
I don't see why you speak of abuse, bit of abuse would be, say if you replaced
range(5) by '12345' to win a char; but otoh I think you misspelled any() for all().
Cheers BB
The OP's code break'ed (broke?) upon the first success, rather
than checking all of them. Thus, it would be any() rather than
all(). Using all() would require 5 successful calls to
CheckIP(), rather than one-out-of-five successful calls.
As for abuse, the "for _ in iterable" always feels a little hokey
to me. It works, but feels warty.
-tkc
Use the for statement's "else" clause: it's there to allow you to
specify code to be executed only when the loop terminates normally.
for i in range(5):
if CheckIP():
break
else:
sys.exit("Could not verify IP address")
... remainder of program ...
regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/
Right. So it could also be written " if all(not CheckIP()... ". Perhaps more
closely re-telling the OP's ?
>
> As for abuse, the "for _ in iterable" always feels a little hokey to
> me. It works, but feels warty.
I guess this means you did not learn Prolog before Python ?
Cheers, BB