super class 的 __init__ 未使用数据 class 调用
super class's __init__ is not called using dataclass
我正在通过从 asyncio.Future
继承一些自定义属性来创建作业 class,并希望作业实例像原始 Future 一样运行。
当我在协同程序中调用 job.set_result
时,它引发了一个 Future object is not initialized error
,然后我尝试通过调用 asyncio.ensure_future
来初始化未来,但出现了同样的错误。
我尝试了更多,发现 future 通常是由 loop.create_future()
创建的,但是没有创建自定义 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())
问题是 Future
不是数据 class,但是您的 Job
class 继承自它并使用 @dataclass
装饰器。这会导致无法调用 Future.__init__
并因此无法初始化未来对象。
要解决此问题,请不要在第一个部分使用 @dataclass
装饰器
地方。相反,编写一个明确的 __init__
来设置必要的属性,并调用 super().__init__()
来正确初始化 Future
。
您需要自己调用超类构造函数,这是数据类 __init__
无法做到的 because of reasons. But you also shouldn't try to re-implement __init__
yourself, since it is not exactly intuitive,您可能会搞砸。
正确的做法(假设您想继续使用 @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())
我正在通过从 asyncio.Future
继承一些自定义属性来创建作业 class,并希望作业实例像原始 Future 一样运行。
当我在协同程序中调用 job.set_result
时,它引发了一个 Future object is not initialized error
,然后我尝试通过调用 asyncio.ensure_future
来初始化未来,但出现了同样的错误。
我尝试了更多,发现 future 通常是由 loop.create_future()
创建的,但是没有创建自定义 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())
问题是 Future
不是数据 class,但是您的 Job
class 继承自它并使用 @dataclass
装饰器。这会导致无法调用 Future.__init__
并因此无法初始化未来对象。
要解决此问题,请不要在第一个部分使用 @dataclass
装饰器
地方。相反,编写一个明确的 __init__
来设置必要的属性,并调用 super().__init__()
来正确初始化 Future
。
您需要自己调用超类构造函数,这是数据类 __init__
无法做到的 because of reasons. But you also shouldn't try to re-implement __init__
yourself, since it is not exactly intuitive,您可能会搞砸。
正确的做法(假设您想继续使用 @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())