您应该只使用__init__。您正在创建一个常规类实例首先,然后在该实例上等待。这是两个独立的操作。
例如,您可以先创建实例,然后单独等待它:
my_class = MyClass(my_parameter)
result_from_coroutine = await my_class
或者您可以从中创建一个任务并让事件循环执行它
my_class = MyClass(my_parameter)
task = asyncio.create_task(my_class) # the loop will await the task
# ...
if task.done():
result_from_coroutine = task.result()
__await__ 方法是 await 或事件循环用来驱动协程的方法。同样的分离也适用于协程函数(用async def 定义);当您调用它们时,它们也会创建一个新的协程对象,您不必立即等待它们。您可以在其他时间对结果使用await。
如果您正在寻找异步实例创建,那么您可以通过将__new__ method 变成协程来解决这个问题:
>>> class Async:
... async def __new__(cls):
... instance = super().__new__(cls)
... return instance
...
>>> Async()
<coroutine object Async.__new__ at 0x103654148>
等待协程将创建实际实例并返回它。
考虑到这确实意味着__init__ 方法将被跳过;后者仅在__new__方法直接返回类(或子类)的实例时调用,协程不是这样的实例。您必须自己明确地这样做:
class Async:
async def __new__(cls, *args, **kwargs):
instance = super().__new__(cls)
instance.__init__(*args, **kwarg)
return instance
此时您可以决定将__init__ 方法也设为协程。
请注意,这确实违反了规定。我会把调用依赖协程推迟到以后。
例如,您可以将参数存储到实例上的类中,并在等待实例时使用这些参数(通过调用__await__),就像您链接到建议的帖子一样。