7

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 部分:基于延续的框架

4

5 回答 5

5

您引用的文章包含指向“资源”部分中的Continuations Made Simple And Illustrated的链接,其中讨论了 Python 语言中的 continuation。

于 2008-11-23T18:33:09.463 回答
2

看一下制作生成器的yield语句。

我不会说任何红宝石,但看起来你正在寻找这个:

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


for i in loop():
    print "pass"

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

于 2008-11-23T18:31:52.930 回答
2

使用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)
于 2008-11-23T23:01:14.213 回答
2

有许多在特殊情况下有效的弱解决方法(请参阅此问题的其他答案),但没有 Python 语言构造等效于callcc或可用于构建等效于callcc.

您可能想尝试Stackless Pythongreenlet Python 扩展,它们都提供协程,基于它们可以构建一次性延续,但这仍然比 Ruby callcc(提供完整延续)弱。

于 2010-12-01T20:00:43.837 回答
0
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()
于 2008-11-23T20:52:30.120 回答