当前位置: 首页 > 知识库问答 >
问题:

Python-在特定类的非异步初始化中等待异步IO任务

左丘智渊
2023-03-14

我正在用一个\uuuu init\uuu函数和另一个函数创建一个python类,比如说f\uuuu init\uuu函数不是异步的,但另一个函数是异步的。现在,我正在尝试执行\uuuu init\uuuu中的另一个函数。

我调查过的事情:

  • 我发现一些代码带有get\u event\u loop/get\u running\u loop并一直运行到\u完成,但这会导致运行时错误,即事件循环已经在运行。
  • 我看过关于nest_asyncio的评论,但它似乎有点脏。
  • 此外,我还使用create_task、gather和wait尝试了几种方法。但在这种情况下,代码不会等待任务完全执行。
  • 我可以先调用构造函数,然后用wait调用第二个函数来拆分它,但是我希望在构造函数中调用第二个函数

请注意,这在Azure Function应用程序上下文中。

一些示例代码

import asyncio
class myClass(object):
    def __init__(self, arg1, arg2):
        self.arg1 = arg1
        self.arg2 = arg2
        #asyncio.create_task(self.f('abc'))
        self.loop = asyncio.get_event_loop()
        self.loop.run_until_complete(self.f('abc'))
    
    async def f(self, x):
        await asyncio.sleep(1)
        self.x = x
        
if __name__ == '__main__':
    cl = myClass(1,2)
    print(cl.x)

这在这个简单的上下文中运行良好,但在更复杂的上下文中就不行了,例如在Azure Functions中,我试图在函数中使用myClass,然后希望使用其"x"属性。

共有1个答案

仲孙小云
2023-03-14

\uuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。

\uuuu init\uuuu中启动一些异步任务,并提供第二种方法来等待它们:

import asyncio
class myClass(object):
    """ must await on obj.finish_init() before the object can be used """
    def __init__(self, arg1, arg2):
        self.arg1 = arg1
        self.arg2 = arg2
        self._finish_init_promise = asyncio.create_task(self.f('abc'))
        #self.loop = asyncio.get_event_loop()
        #self.loop.run_until_complete(self.f('abc'))
    async def finish_init(self):
        await self._finish_init_promise
        return self
    
    async def f(self, x):
        await asyncio.sleep(1)
        self.x = x
async def main():
    cl = await myClass(1,2).finish_init()
    print(cl.x)
if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(main())

但是,构造一个不完整的对象可能是不可取的(您可能需要一个布尔值来指示它是否准备就绪),因此另一种方法是提供一个异步classmethod来准备数据,然后将该数据传递给构造函数:

import asyncio
class myClass(object):
    def __init__(self, arg1, arg2, x):
        self.arg1 = arg1
        self.arg2 = arg2
        self.x = x
    @classmethod
    async def make(cls, arg1, arg2):
        x = cls.obvious_example_will_be_replaced_with_real_use_case('abc')
        return cls(arg1, arg2, x)
    @staticmethod
    async def obvious_example_will_be_replaced_with_real_use_case(x):
        await asyncio.sleep(1)
        return x
async def main():
    cl = await myClass.make(1,2)
    print(cl.x)
if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(main())

 类似资料:
  • 我通读了Dart/flatter中的Async/Await/then,试图理解为什么aysnc函数中的Await不会等到完成后再继续。在我的UI中,有一个按钮调用一个异步方法来返回一个位置,该位置总是返回null,并且不等待函数完成。 该函数将调用推送到一个新的UI页面,该页面选择一个位置,并应返回一个结果。如何使该函数等待结果?我不是在使用异步吗?

  • 我试图在react/electron项目中使用async/await,但它不起作用。我想要的是获取docker容器状态列表。但是安慰。日志(列表)返回未定义的。 有人能帮我吗?:)

  • SOFABoot 提供了模块并行启动以及 Spring Bean 异步初始化能力,用于加快应用启动速度。本文介绍如何使用 SOFABoot 异步初始化 Spring Bean 能力以提高应用启动速度。 使用场景 在实际使用 Spring/Spring Boot 开发中,一些 Bean 在初始化过程中执行准备操作,如拉取远程配置、初始化数据源等等。在应用启动期间,这些 Bean 会增加 Spring

  • 问题内容: 我想同时下载一些文件,例如100个文件。因此,我决定将下载线程添加到调度队列中,GCD会调整同时运行多少个线程。 这里的问题是:中的块将立即完成,因为它将在另一个线程上运行。因此,如果长度为100,它将立即创建100个线程。 如何配置块以等待下载任务完成?我不想使用,因为它只允许同时运行一个下载任务。 问题答案: 要扩展Abhinav的答案,您应该: 使用创建一个组。 在开始每个下载任

  • 我正在用。NET核心编写一个ASP.NET MVC站点。我试图封装一些常见的异常处理。在基类中,我有这个方法。 从继承自该基类的控制器中,我使用如下方法: 假设_someservice.getAsync()方法如下: 这工作得很好,将捕获基类方法中的异常并返回NotFound结果。 但是,我希望避免从SomeService.GetAsync方法调用。result。我读到的任何地方都说不要那样做,因

  • 在IO编程一节中,我们已经知道,CPU的速度远远快于磁盘、网络等IO。在一个线程中,CPU执行代码的速度极快,然而,一旦遇到IO操作,如读写文件、发送网络数据时,就需要等待IO操作完成,才能继续进行下一步操作。这种情况称为同步IO。 在IO操作的过程中,当前线程被挂起,而其他需要CPU执行的代码就无法被当前线程执行了。 因为一个IO操作就阻塞了当前线程,导致其他代码无法执行,所以我们必须使用多线程