使用 asyncio 的相互递归协程

2023-11-26

我有一个假设,如果我用 asyncio 编写相互递归协程,它们不会遇到最大递归深度异常,因为事件循环正在调用它们(并且像蹦床一样运行)。然而,当我这样写时,情况并非如此:

import asyncio

@asyncio.coroutine
def a(n):
    print("A: {}".format(n))
    if n > 1000: return n
    else: yield from b(n+1)

@asyncio.coroutine
def b(n):
    print("B: {}".format(n))
    yield from a(n+1)

loop = asyncio.get_event_loop()
loop.run_until_complete(a(0))

当这个运行时,我得到RuntimeError: maximum recursion depth exceeded while calling a Python object.

有没有办法阻止堆栈在带有 asyncio 的递归协程中增长?


为了防止堆栈增长,您必须允许每个协程在安排下一个递归调用后实际退出,这意味着您必须避免使用yield from。相反,你使用asyncio.async (or asyncio.ensure_future如果使用 Python 3.4.4+) 通过事件循环安排下一个协程,并使用Future.add_done_callback安排回调在递归调用返回后运行。然后每个协程返回一个asyncio.Future对象,其结果集位于回调中,该回调在其计划的递归调用完成时运行。

如果您实际看到代码,可能最容易理解:

import asyncio

@asyncio.coroutine
def a(n):
    fut = asyncio.Future()  # We're going to return this right away to our caller
    def set_result(out):  # This gets called when the next recursive call completes
        fut.set_result(out.result()) # Pull the result from the inner call and return it up the stack.
    print("A: {}".format(n))
    if n > 1000: 
        return n
    else: 
        in_fut = asyncio.async(b(n+1))  # This returns an asyncio.Task
        in_fut.add_done_callback(set_result) # schedule set_result when the Task is done.
    return fut

@asyncio.coroutine
def b(n):
    fut = asyncio.Future()
    def set_result(out):
        fut.set_result(out.result())
    print("B: {}".format(n))
    in_fut = asyncio.async(a(n+1))
    in_fut.add_done_callback(set_result)
    return fut

loop = asyncio.get_event_loop()
print("Out is {}".format(loop.run_until_complete(a(0))))


Output:
A: 0
B: 1
A: 2
B: 3
A: 4
B: 5
...
A: 994
B: 995
A: 996
B: 997
A: 998
B: 999
A: 1000
B: 1001
A: 1002
Out is 1002

现在,您的示例代码实际上并未返回n一直备份堆栈,因此您可以制作功能相同但更简单的东西:

import asyncio

@asyncio.coroutine
def a(n):
    print("A: {}".format(n))
    if n > 1000: loop.stop(); return n
    else: asyncio.async(b(n+1))

@asyncio.coroutine
def b(n):
    print("B: {}".format(n))
    asyncio.async(a(n+1))

loop = asyncio.get_event_loop()
asyncio.async(a(0))
loop.run_forever()

但我怀疑你真的想回来n一路备份。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 asyncio 的相互递归协程 的相关文章

  • 如何在python中读取多个文件中的文本

    我的文件夹中有许多文本文件 大约有 3000 个文件 每个文件中第 193 行是唯一包含重要信息的行 我如何使用 python 将所有这些文件读入 1 个文本文件 os 模块中有一个名为 list dir 的函数 该函数返回给定目录中所有文
  • 将字符串转换为带有毫秒和时区的日期时间 - Python

    我有以下 python 片段 from datetime import datetime timestamp 05 Jan 2015 17 47 59 000 0800 datetime object datetime strptime t
  • 如何收集列表、字典等中重复计算的结果(或制作修改每个元素的列表的副本)?

    There are a great many existing Q A on Stack Overflow on this general theme but they are all either poor quality typical
  • 更改自动插入 tkinter 小部件的文本颜色

    我有一个文本框小部件 其中插入了三条消息 一条是开始消息 一条是结束消息 一条是在 单位 被摧毁时发出警报的消息 我希望开始和结束消息是黑色的 但被毁坏的消息 参见我在代码中评论的位置 插入小部件时颜色为红色 我不太确定如何去做这件事 我看
  • 如何使用 Scrapy 从网站获取所有纯文本?

    我希望在 HTML 呈现后 可以从网站上看到所有文本 我正在使用 Scrapy 框架使用 Python 工作 和xpath body text 我能够获取它 但是带有 HTML 标签 而且我只想要文本 有什么解决办法吗 最简单的选择是ext
  • __del__ 真的是析构函数吗?

    我主要用 C 做事情 其中 析构函数方法实际上是为了销毁所获取的资源 最近我开始使用python 这真的很有趣而且很棒 我开始了解到它有像java一样的GC 因此 没有过分强调对象所有权 构造和销毁 据我所知 init 方法对我来说在 py
  • 安装后 Anaconda 提示损坏

    我刚刚安装张量流GPU创建单独的后环境按照以下指示here https github com antoniosehk keras tensorflow windows installation 但是 安装后当我关闭提示窗口并打开新航站楼弹出
  • 在 NumPy 中获取 ndarray 的索引和值

    我有一个 ndarrayA任意维数N 我想创建一个数组B元组 数组或列表 其中第一个N每个元组中的元素是索引 最后一个元素是该索引的值A 例如 A array 1 2 3 4 5 6 Then B 0 0 1 0 1 2 0 2 3 1 0
  • IRichBolt 在storm-1.0.0 和 pyleus-0.3.0 上运行拓扑时出错

    我正在运行风暴拓扑 pyleus verbose local xyz topology jar using storm 1 0 0 pyleus 0 3 0 centos 6 6并得到错误 线程 main java lang NoClass
  • 如何将 numpy.matrix 提高到非整数幂?

    The 运算符为numpy matrix不支持非整数幂 gt gt gt m matrix 1 0 0 5 0 5 gt gt gt m 2 5 TypeError exponent must be an integer 我想要的是 oct
  • ExpectedFailure 被计为错误而不是通过

    我在用着expectedFailure因为有一个我想记录的错误 我现在无法修复 但想将来再回来解决 我的理解expectedFailure是它会将测试计为通过 但在摘要中表示预期失败的数量为 x 类似于它如何处理跳过的 tets 但是 当我
  • Python:尝试检查有效的电话号码

    我正在尝试编写一个接受以下格式的电话号码的程序XXX XXX XXXX并将条目中的任何字母翻译为其相应的数字 现在我有了这个 如果启动不正确 它将允许您重新输入正确的数字 然后它会翻译输入的原始数字 我该如何解决 def main phon
  • Numpy 优化

    我有一个根据条件分配值的函数 我的数据集大小通常在 30 50k 范围内 我不确定这是否是使用 numpy 的正确方法 但是当数字超过 5k 时 它会变得非常慢 有没有更好的方法让它更快 import numpy as np N 5000
  • Python 3 中“map”类型的对象没有 len()

    我在使用 Python 3 时遇到问题 我得到了 Python 2 7 代码 目前我正在尝试更新它 我收到错误 类型错误 map 类型的对象没有 len 在这部分 str len seed candidates 在我像这样初始化它之前 se
  • 在Python中重置生成器对象

    我有一个由多个yield 返回的生成器对象 准备调用该生成器是相当耗时的操作 这就是为什么我想多次重复使用生成器 y FunctionWithYield for x in y print x here must be something t
  • 设置 torch.gather(...) 调用的结果

    我有一个形状为 n x m 的 2D pytorch 张量 我想使用索引列表来索引第二个维度 可以使用 torch gather 完成 然后然后还设置新值到索引的结果 Example data torch tensor 0 1 2 3 4
  • 如何从没有结尾的管道中读取 python 中的 stdin

    当管道来自 打开 时 不知道正确的名称 我无法从 python 中的标准输入或管道读取数据 文件 我有作为例子管道测试 py import sys import time k 0 try for line in sys stdin k k
  • glpk.LPX 向后兼容性?

    较新版本的glpk没有LPXapi 旧包需要它 我如何使用旧包 例如COBRA http opencobra sourceforge net openCOBRA Welcome html 与较新版本的glpk 注意COBRA适用于 MATL
  • 在python中,如何仅搜索所选子字符串之前的一个单词

    给定文本文件中的长行列表 我只想返回紧邻其前面的子字符串 例如单词狗 描述狗的单词 例如 假设有这些行包含狗 hotdog big dog is dogged dog spy with my dog brown dogs 在这种情况下 期望
  • 改变字典的哈希函数

    按照此question https stackoverflow com questions 37100390 towards understanding dictionaries 我们知道两个不同的字典 dict 1 and dict 2例

随机推荐

  • “独特粒子归因”违规

    我编写了以下 简化的 架构来验证我收到的一些 XML 文件
  • Chrome JavaScript 开发者控制台:是否可以在不换行的情况下调用 console.log() ?

    我想使用 console log 来记录消息without每次调用 console log 后添加一个新行 这可能吗 不 这是不可能的 如果您希望将所有内容都放在一行中 或者将输出放在其他地方 例如 另一个窗口 则必须保留一个字符串并连接起
  • Selenium 和异步 JavaScript 调用

    我对 Selenium 和 JavaScript 回调函数很陌生 我有一个无法自己解决的大问题 我需要使用 JavaScript 指定一个变量 如果我使用 GoogleChrome 打开页面并使用控制台输入我的 JavaScript 代码
  • 重大地点变更 - 我们有什么保证?

    我目前正在编写一个移动 iOS 应用程序 该应用程序使用 iOS 重要位置更改服务来管理大量地理围栏 当我们从 CoreLocation 框架收到此消息时启用和禁用地理围栏 苹果开发者网站上写道 仅当设备位置发生重大变化 例如 500 米或
  • 在 Spring Boot 中发送多部分响应

    我正在研究在 Spring Boot 中开发的 api 现在我有一个 API 我必须在其中发送包含一个二进制文件和 xml 的响应 两者将由多部分边界分隔 那么有什么办法可以做到这一点吗 在 Spring Boot 中 尝试按照多部分发送响
  • 选择计数/重复项

    我有一张包含所有美国邮政编码的表格 每行包含邮政编码的城市和州名称 我正在尝试获取出现在多个州的城市列表 如果同一城市没有 X 个邮政编码 这不会是问题 所以基本上 我只想将一个州的城市算作 1 而不是将城市 州计数 7 次 因为该城市 州
  • 使用 pymongo 在 mongodb 中按 ObjectId 搜索

    我需要使用 pymongo 使用 python 搜索 ObjectId 但总是收到此错误 有什么想法如何搜索吗 import pymongo from pymongo import MongoClient from pymongo impo
  • 如何评估来自 stdin 的 PowerShell 脚本输入

    我想在 PowerShell 中评估 StdIn 的内容 如下所示 echo echo 12 powershell noprofile noninteractive command input iex Output echo 12 很遗憾
  • 如何在 C# 应用程序启动时立即运行代码?

    我已经将一些代码放在了公共内部MainWindow 但我一这样做就不断收到一些晦涩的 XAML 解析错误 不是在我的计算机上 而是在我尝试过的其他 3 台计算机上 是否有一种在应用程序启动时立即运行代码的首选方法 理论上是我希望它打电话回家
  • 如果函数指针不需要 & 符号,为什么 boost::bind 需要一个?

    我一直相信函数指针不需要 符号 然而 我见过的每一个使用的例子boost bind显示一个 并且我的编译器 在大多数情况下 如果省略它 则会给出通常难以理解的错误消息 synchronize boost bind Device asyncU
  • 是否可以通过 Chrome 扩展中的上下文菜单项调用内容脚本方法?

    我正在尝试使用上下文菜单项来调用在内容脚本中编写的方法 那可能吗 正如我所尝试的那样 上下文菜单只能在后端执行操作 E g A generic onclick callback function function genericOnClic
  • 如何在 Linux UVC 驱动程序中启用 UVC_QUIRK_FIX_BANDWIDTH 怪癖?

    我目前正在尝试运行 2webcams在 Wandboard 板上 它们必须共享 USB 集线器 问题是 当前的驱动程序实现 仅限 YUV 使 USB 集线器饱和 最终我只能连接一台相机 然而 UVC 驱动程序的实现有一个怪癖kind情况等
  • dplyr sample_n 其中 n 是分组变量的值

    我有以下分组数据框 我想使用该功能dplyr sample n从此数据框中为每个组提取行 我想使用分组变量的值NDG每组中的行数作为从每组中提取的行数 gt dg tmp lt structure list Gene c CAMK1 GHR
  • 下载功能因文件过大而失败

    你好 我的下载功能 protected void downloadFunction string fileName string filePath D SoftwareFiles LogMessageToFile Download star
  • 具有 ASPN、应用内购买等的多个应用程序中的应用程序 ID 和捆绑种子 ID

    我将创造多个销售版本具有推送通知功能的同一应用程序 酷应用 完整版 CoolApp Free 免费 功能有限 版本 酷应用程序中的应用程序 免费版 可通过应用内升级至完整版 购买 在 Apple Program Portal 中注册 App
  • 在正则表达式中将空格转换为制表符

    在正则表达式中如何表达以下内容 foreach line look at the beginning of the string and convert every group of 3 spaces to a tab Stop once
  • 我应该如何在 JavaScript 中“屈服”?

    我对现代 JavaScript ES8 有点陌生 异步产生的首选方法是什么 即在事件循环的未来迭代中继续执行脚本 使用await 我看到了以下选项 async function yield1 await Promise resolve co
  • 将 std::unique_ptr 与分配器一起使用

    这次我尝试使用分配器 感觉有很多机会泄漏资源 所以我想如果我用怎么办std unique ptr来处理它们 我试着用我的手std vector的分配器 我的代码是这样的 allocator include
  • PHP 不带引号的数组访问

    我在现有的 php 源代码中发现了一个现象 不带撇号的字段访问 如下所示 GET test 我不确定 也不知道这是一种可能的方式 所以我写了一个简短的例子来测试 echo Array Test fields without apostrop
  • 使用 asyncio 的相互递归协程

    我有一个假设 如果我用 asyncio 编写相互递归协程 它们不会遇到最大递归深度异常 因为事件循环正在调用它们 并且像蹦床一样运行 然而 当我这样写时 情况并非如此 import asyncio asyncio coroutine def