在 Wizard 类中,我想将属性 wand 设置为协程 magic 返回的值。
class Wizard:
async def acquire_wand(self):
self.wand = await magic()
然而,此代码被认为是“糟糕的 Python”,因为 wand 未在 __init__ 中定义。不过,我不能在 __init__ 中定义它,因为 await 只能在 asynchronous 函数中使用。
class Wizard:
def __init__(self):
self.wand = None
async def acquire_wand(self):
self.wand = await magic()
async def perform_spell(self):
if self.wand is None:
await self.acquire_wand()
self.wand.wave()
我可以在 __init__ 中将 wand 设置为 None 并在任何地方使用 if self.wand is None:可以访问,但这看起来很困惑且笨拙。
我怎样才能确保 wand 在整个类(class)中都有定义?
请您参考如下方法:
从技术上讲,重写 __new__ 方法有一个技巧:
class InitCoroMixin:
""" Mixin for create initialization coroutine
"""
def __new__(cls, *args, **kwargs):
""" This is magic!
"""
instance = super().__new__(cls)
@asyncio.coroutine
def coro():
instance.__init__(*args, **kwargs)
yield from instance.__ainit__()
return instance
return coro()
@asyncio.coroutine
def __ainit__(self):
raise NotImplementedError
参见 aiohttp_traversal完整示例的代码。
但我强烈反对这种方法:在构造函数中使用 I/O 通常不是一个好主意,请考虑一下。
