English 中文(简体)
Python等价于具有Ruby的continuations
原标题:
  • 时间:2008-11-23 18:25:01
  •  标签:

以下 Ruby 代碼的 Python 等效代碼是什麼?

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

参考: 轻量级开发成功的秘诀,第9部分:基于Continuations的框架

最佳回答

你引用的文章包含一个链接指向“在资源部分中的简单且形象的Continuations Made Simple And Illustrated”,其中讲述了Python语言中的continuations。

问题回答

看一下使用yield语句创建生成器的方法:yield语句。

我不会说任何Ruby,但是看起来你在寻找这个:

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


for i in loop():
    print "pass"

编辑:我意识到这基本上是真正延续的一种专业化,但对于大多数目的来说应该足够了。使用yield返回延续,通过生成器上的.next()消息(通过只调用loop()返回)重新进入。

使用generator_tools (安装方法:$ 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 s 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())

输出:

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

有许多弱的解决方法只适用于特定情况(详见其他答案),但Python没有与callcc等效的语言构造,也无法用于构建类似callcc的东西。

您可以尝试使用Stackless Pythongreenlet Python扩展程序,两者都提供协程,基于此可以构建一次性的连续操作,但这仍然比Ruby的callcc弱(该功能提供完整的连续操作)。

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()




相关问题
热门标签