简体   繁体   English

Python相当于Ruby的延续

[英]Python equivalent of continuations with Ruby

What is the Python equivalent of the following code in Ruby? 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

Reference: Secrets of lightweight development success, Part 9: Continuations-based frameworks 参考: 轻量级开发成功的秘诀,第9部分:基于Continuations的框架

您引用的文章在参考资料部分中包含指向Continuations Made Simple和I​​llustrated的链接,该部分讨论了Python语言中的延续。

take a look at the yield statement to make generators. 看一下yield语句来生成生成器。

I don't speak any ruby, but it seems like you're 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 realize this is basically a specialization of real continuations, but it should be sufficient for most purposes. 编辑:我意识到这基本上是真实延续的特化,但它应该足以满足大多数目的。 Use yield to return the continuation and the .next() message on the generator (returned by just calling loop() ) to reenter. 使用yield返回生成器上的continuation和.next()消息(仅通过调用loop()返回)重新输入。

Using generator_tools (to install: ' $ easy_install generator_tools '): 使用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())

Output: 输出:

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

There are many weak workarounds which work in special cases (see other answers to this question), but there is no Python language construct which is equivalent to callcc or which can be used to build something equivalent to callcc . 有许多弱变通方法在特殊情况下工作(请参阅此问题的其他答案),但没有Python语言构造等同于callcc或可用于构建等同于callcc东西。

You may want to try Stackless Python or the greenlet Python extension, both of which provide coroutines, based on which it is possible to build one-shot continutations, but that's still weaker than Ruby's callcc (which provides full continuations). 你可能想尝试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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM