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