Pause in a loop
Jp Calderone
exarkun at intarweb.us
Tue Jul 22 06:57:35 EDT 2003
On Tue, Jul 22, 2003 at 10:00:27AM +0000, manuel wrote:
>
> I've two modules: main.py and eval.py
>
> Eval.py is imported in main.py, but I've a loop
> in eval.py that must call a function in main.py...
>
> I can't import main.py in eval.py too, because
> that would create an import loop.
>
> But I'm thinking a different solution:
> a pause in a loop to return periodically an
> output. It's possible?
>
Generators, or "resumable functions" may be one possible solution for
this:
from __future__ import generators # Necessary until Python 2.3
class MoreWorkToDo:
pass
class NearlyDone:
pass
def f1():
for i in xrange(100):
do_something_expensive_and_slow()
yield MoreWorkToDo
for i in xrange(10):
cleanup_a_little()
yield NearlyDone
def f2():
for x in f1():
print str(x),
Another possibility is to use a callback:
class MoreWorkToDo:
pass
class NearlyDone:
pass
def f1(perLoop):
for i in xrange(100):
do_something_expensive_and_slow()
perLoop(MoreWorkToDo)
for i in xrange(10):
cleanup_a_little()
perLoop(NearlyDone)
def cbFunc(v):
print str(v),
def f2():
f1(cbFunc)
Still another approach might create an iterator out of an explicit state
machine:
class MoreWorkToDo:
pass
class NearlyDone:
pass
class Worker:
def __iter__(self):
return _WorkerIter()
class _WorkerIter:
def __init__(self):
self.state = 'working'
self.workCount = 100
self.cleanCount = 10
def next(self):
return getattr(self, 'state_' + self.state)()
def state_working(self):
do_something_expensive_and_slow()
self.workCount -= 1
if self.workCount <= 0:
self.state = 'cleanup'
return MoreWorkToDo
def state_cleanup(self):
cleanup_a_little()
self.cleanCount -= 1
if self.cleanCount <= 0:
raise StopIteration()
return NearlyDone
def f2():
for x in Worker():
print str(x),
The iterator solution is very similar to the generator solution (in fact,
the generator also creates an iterator, just a different kind) but as you
can see is a bit more code. The advantage is the iterator version may be
able to continue if an unexpected exception is raised in one of the calls to
`next', whereas the generator form will never be able to do so. The
iterator version is also pickleable.
Hope this helps,
Jp
>
> thanks,
>
> Manuel
>
>
> --
> http://mail.python.org/mailman/listinfo/python-list
--
"If you find a neighbor in need, you're responsible for serving that
neighbor in need, you're responsible for loving a neighbor just like you'd
like to love yourself." -- George W. Bush, Sept. 16, 2002
More information about the Python-list
mailing list