【问题标题】:Python equivalent of continuations with RubyPython 等价于 Ruby 的延续
【发布时间】:2010-09-23 16:34:17
【问题描述】:

以下代码在 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

参考:Secrets of lightweight development success, Part 9: Continuations-based frameworks

【问题讨论】:

    标签: python ruby continuations


    【解决方案1】:

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

    【讨论】:

      【解决方案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() 即可返回)重新进入。

      【讨论】:

        【解决方案3】:

        使用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)
        

        【讨论】:

        • generator_tools 可以复制的内容非常有限,请参阅其文档。我不会提名 generator_tools 来替代 callcc。
        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:
          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()
          

          【讨论】:

            猜你喜欢
            • 2019-08-15
            • 2012-11-26
            • 1970-01-01
            • 2011-08-18
            • 2019-03-14
            • 2012-02-21
            • 2011-03-18
            • 2014-05-15
            • 1970-01-01
            相关资源
            最近更新 更多