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)
您需要自己调用超类构造函数,这是数据类由于某些原因__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)