Python equivalent of continuations with Ruby

What is the Python equivalent for the following code in Ruby?

def loop cont=nil for i in 1..4 puts i callcc {|continuation| cont=continuation} if i==2 end return cont end > c=loop 1 2 3 4 > c.call 3 4 

Ref: Secrets to Success in Easy Development, Part 9: Continuity Based Framework

+7
python ruby continuations
source share
5 answers

This article provides a link to Continuations Made Simple And Illustrated in the Resources section, which talks about sequels in Python.

+5
source share

look at yield to create generators.

I'm not talking about ruby, but it looks like you are looking for this:

 def loop(): for i in xrange(1,5): print i if i == 2: yield for i in loop(): print "pass" 

Edit: I understand that this is mainly a specialization of real sequels, but this should be enough for most purposes. Use yield to return the continuation and the .next() message on the generator (returned when loop() called) to re-enter.

+2
source share

Using generator_tools (for installation: ' $ easy_install generator_tools '):

 from generator_tools import copy_generator def _callg(generator, generator_copy=None): for _ in generator: # run to the end pass if generator_copy is not None: return lambda: _callg(copy_generator(generator_copy)) def loop(c): c.next() # advance to yield expression return _callg(c, copy_generator(c)) if __name__ == '__main__': def loop_gen(): i = 1 while i <= 4: print i if i == 2: yield i += 1 c = loop(loop_gen()) print("c:", c) for _ in range(2): print("c():", c()) 

Output:

 1 2 3 4 ('c:', <function <lambda> at 0x00A9AC70>) 3 4 ('c():', None) 3 4 ('c():', None) 
+2
source share

There are many weak workarounds that work in special cases (see other answers to this question), but there is no Python language construct that is equivalent to callcc or that can be used to create something equivalent to callcc .

You can try Stackless Python or the greenlet Python Extension, both of which provide coroutines that can be used to build one-time permutations, but which are still weaker than Ruby callcc (which provides a full continuation).

+2
source share
 def loop(): def f(i, cont=[None]): for i in range(i, 5): print i if i == 2: cont[0] = lambda i=i+1: f(i) return cont[0] return f(1) if __name__ == '__main__': c = loop() c() 
0
source share

All Articles