超类的 __init__ 未使用数据类调用

BAK*_* ZQ 4 python python-3.x python-dataclasses

我正在通过继承asyncio.Future一些自定义属性来创建一个作业类,并期望作业实例的功能与原始 Future 类似。

当我job.set_result在协程内部调用时,它会引发 a Future object is not initialized error,然后我尝试通过调用初始化 futureasyncio.ensure_future并出现相同的错误。

我尝试了更多,发现未来通常是由 创造的loop.create_future(),但是,没有选项来创建我的自定义未来。

下面是一个示例,如何初始化我的自定义未来?

import asyncio
from dataclasses import dataclass

@dataclass
class Job(asyncio.Future):
    job_task: Callable
    real_future: asyncio.Future = None
    something: str = None

    def schedule(self):
        async def run():
            res = await self.job_task()
            self.set_result(res) # raise error, future not initialized
            return res
        self.real_future = asyncio.ensure_future(run())

async def main():
    async def task():
        await asyncio.sleep(1)
        return 1
    job = Job(task)
    job.schedule()
    await job

asyncio.run(main())

Run Code Online (Sandbox Code Playgroud)

Arn*_*rne 5

您需要自己调用超类构造函数,这是数据类由于某些原因__init__无法执行的操作。但你也不应该尝试重新实现自己,因为它并不完全直观__init__,而且您可能会搞砸。

正确的方法(假设您想继续使用@dataclass装饰器)是利用__post_init__数据类提供的钩子:

@dataclass
class Job(asyncio.Future):
    job_task: Callable
    real_future: asyncio.Future = None
    something: str = None

    def __post_init__(self)
        super().__init__()

    def schedule(self):
        async def run():
            res = await self.job_task()
            self.set_result(res)  # works now
            return res
        self.real_future = asyncio.ensure_future(run())
Run Code Online (Sandbox Code Playgroud)