我一直在尝试使用协同程序绕过 Python 的递归限制,并通过反复试验得出了这段代码递归计算斐波那契数:
import asyncio
from typing import Callable, Coroutine
def recursive(f: Callable[[int], Coroutine]):
return lambda x: asyncio.create_task(f(x))
m = [0, 1]
@recursive
async def f(x: int):
if len(m) <= x:
m.append(await f(x - 1) + await f(x - 2))
return m[x]
async def main():
print(await f(2000))
asyncio.run(main())
# prints 4224696333392304878706725602341482782579852840250681098010280137314308
# 58437013070722412359963914151108844608753890960360764019471164359602927198331
# 25987373262535558026069915859152294924539049987222567953169828744824729922639
# 01833716778060607011615497886719879858311468870876264597369086722884023654422
# 29524334796448013951534956297208765265606952980649984197744872015561280266540
# 4554171717881930324025204312082516817125
有人可以解释为什么这不会导致无限递归吗?如链接文件中的评论所述,我希望 Python 急切地计算 lambda 中的
f(x)
,这似乎会导致无限递归。令我惊讶的是,在使用调试器单步执行代码时,lambda 似乎完全跳过了对 f(x)
的评估,并且以某种方式立即能够将协程传递给 asyncio.create_task
.
我应该补充一点,这是在 Python 3.10.10 上。