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 语言中的 continuation。
看一下制作生成器的yield语句。
我不会说任何红宝石,但看起来你正在寻找这个:
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()