Pause in a loop

M

manuel

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?


thanks,

Manuel
 
M

Michael Peuser

manuel said:
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...
......

How is that loop activated in the first place? If you activate it by a call
just provide your main-proc as a callback parameter in that call...

Kindly
Michael
 
J

Jp Calderone

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
 
G

Gilles Lenfant

manuel said:
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?


thanks,

Manuel

Send that function to the eval as parameter...

<main.py>
....
import eval

def myfunc(...)
...
def main():
...
eval.eval(x, y, z, myfunc)
....
</main.py>

<eval.py>
....
def eval(x, y, z, afunc):
...
afunc(...)
....
return stuff
....
</eval.py>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top