从 python 的协程对象中检索数据
Posted
技术标签:
【中文标题】从 python 的协程对象中检索数据【英文标题】:Retrieving data from python's coroutine object 【发布时间】:2019-11-24 20:02:00 【问题描述】:我正在尝试学习异步,现在我正在尝试获取一批域的 whois 信息。我找到了这个库aiowhois,但是只有几笔信息,对于我这样的新手来说还不够。
这段代码没有错误,但我不知道如何从解析的whois
变量打印数据,这是协程对象。
resolv = aiowhois.Whois(timeout=10)
async def coro(url, sem):
parsed_whois = await resolv.query(url)
async def main():
tasks = []
sem = asyncio.Semaphore(4)
for url in domains:
task = asyncio.Task(coro(url, sem))
tasks.append(task)
await asyncio.gather(*tasks)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
【问题讨论】:
我认为你可以避免使用任务。只需将gather
直接应用到coro(url, sem)
即可。如果您愿意,可以将任务列表重命名为coros
你用信号量做什么?
这段代码是由其他程序的一部分组成的,我还是不太清楚这里的一切=(
不回答您的问题,而只是为未来提供帮助:尤其是在 gTLD 中,whois 正在消亡,要使用的新协议是 RDAP。由于它基于 HTTPS,任何 HTTP 异步库都可以毫无问题地处理它。除非有很好的理由,现在应该使用 RDAP 而不是 whois 来构建新软件。同样在这两种情况下,输入都应该是域名,而不是 URL。
这个信息对我很有用!!我不知道,非常感谢!
【参考方案1】:
您可以避免使用任务。只需将 collect 直接应用于协程即可。 如果您对差异感到困惑,这个SO QA 可能会对您有所帮助(尤其是第二个答案)。
您可以让每个协程返回其结果,而无需求助于全局变量:
async def coro(url):
return await resolv.query(url)
async def main():
domains = ...
ops = [coro(url) for url in domains]
rets = await asyncio.gather(*ops)
print(rets)
请查看official docs 了解更多关于如何使用gather
或wait
或更多选项的信息
注意:如果你使用的是最新的python版本,你也可以用just来简化循环运行
asyncio.run(main())
注意 2:我已经从我的代码中删除了信号量,因为不清楚你为什么需要它以及在哪里需要它。
【讨论】:
我明白你的意思,会尝试修改我的代码。感谢您的回复 作为 SO 礼仪,如果我的贡献对您有所帮助,请通过投票和/或接受它作为最佳答案来表达您的感激之情。非常感谢 目前我没有足够的 4 声望来投票(11 只需要 15)。但是当我得到它们时我会的。谢谢 你从来没有这样做过,已经快一年了:o【参考方案2】:all_parsed_whois = [] # make a global
async def coro(url, sem):
all_parsed_whois.append(await resolv.query(url))
如果您想要数据尽快可用,您可以 task.add_done_callback()
python asyncio add_done_callback with async def
【讨论】:
以上是关于从 python 的协程对象中检索数据的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin 协程协程取消 ③ ( finally 释放协程资源 | 使用 use 函数执行 Closeable 对象释放资源操作 | 构造无法取消的协程任务 | 构造超时取消的协程任务 )
Kotlin 协程协程取消 ③ ( finally 释放协程资源 | 使用 use 函数执行 Closeable 对象释放资源操作 | 构造无法取消的协程任务 | 构造超时取消的协程任务 )