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

标签 python python-3.x python-3.5 python-asyncio

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

关于python - 我应该如何在 __init__ 中定义一个依赖协程的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37643585/

相关文章:

python - 动态添加可调用类作为实例 "method"

python - 我的函数没有运行,但是当我在函数之外运行代码时它可以工作

mysql - 无法在 CentOS-7 上安装 mysql-devel

Python 查找一些而不是全部自定义包

python - python 请求中的单个 session 多个 post/get

python - 字典到数据框

python - 在 python 中编写轮询函数的更好方法

python - 在正数前附加一个加号

python-3.5 - 为什么我会收到 FileNotFoundError : [Errno 2] No such file or directory: '/sbin/iwlist'

python - Tensorflow:__new__() 在对象检测 API 中得到了一个意外的关键字参数 'serialized_options'