Skip to main content
 首页 » 编程设计

python之我应该如何在 __init__ 中定义一个依赖协程的变量

2025年05月04日14kuangbin

在 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 通常不是一个好主意,请考虑一下。