def iter_except(func, exception, start=None):
'Yield a function repeatedly until it raises an exception'
try:
if start is not None:
yield start()
while 1:
yield func()
except exception:
pass
### Examples ####################################################
if __name__ == '__main__':
# Example using BSDDB's last() and next() methods
import bsddb
db = bsddb.btopen('/tmp/spam.db', 'c')
for i in range(10):
db['%d'%i] = '%d'% (i*i)
for k, v in iter_except(db.next, bsddb.error, start=db.first):
print k, v
# Example of fetching tasks from a priority queue
from random import random
from heapq import heappush, heappop
from functools import partial
pq = []
for i in range(10):
heappush(pq, (random(), 'task %d' % i))
for priority, task in iter_except(partial(heappop, pq), IndexError):
print priority, task
# Example of atomic, destructive reads from a dictionary
d = dict(enumerate('abcdefghi'))
for k, v in iter_except(d.popitem, KeyError):
print k, v
# Example of atomic, destructive reads from a deque
import collections
d = collections.deque('abcdefghi')
for v in iter_except(d.popleft, IndexError):
print v
# Example of iterating over a producer Queue:
import Queue
q = Queue.Queue()
for i in range(10):
q.put('*' * i)
for v in iter_except(q.get_nowait, Queue.Empty):
print v
# Example of iterating destructively over a set
s = set('abracadabra')
for elem in iter_except(s.pop, KeyError):
print elem