以下 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
以下 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
你引用的文章包含一个链接指向“在资源部分中的简单且形象的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 Python或greenlet 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()