Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我应该如何定义依赖于uu init_uu中的协程的变量?_Python_Python 3.x_Python 3.5_Python Asyncio - Fatal编程技术网

Python 我应该如何定义依赖于uu init_uu中的协程的变量?

Python 我应该如何定义依赖于uu init_uu中的协程的变量?,python,python-3.x,python-3.5,python-asyncio,Python,Python 3.x,Python 3.5,Python Asyncio,在classWizard中,我想将属性wand设置为coroutinemagic返回的值 class Wizard: async def acquire_wand(self): self.wand = await magic() 然而,这段代码被认为是“糟糕的Python”,因为wand没有在\uuuu init\uuuu中定义。但是,我无法在\uuuu init\uuuu中定义它,因为等待只能在异步同步函数中使用 class Wizard: def __ini

在class
Wizard
中,我想将属性
wand
设置为coroutine
magic
返回的值

class Wizard:
    async def acquire_wand(self):
        self.wand = await magic()
然而,这段代码被认为是“糟糕的Python”,因为
wand
没有在
\uuuu init\uuuu
中定义。但是,我无法在
\uuuu init\uuuu
中定义它,因为
等待
只能在
异步
同步函数中使用

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()
我可以在
\uuu init\uuuu
中将
魔杖设置为
,如果self.wand为无:
则可以在任何访问它的地方使用
,但这看起来很混乱和笨拙


如何确保在整个课程中定义
wand

将需要
self.wand
的函数包装在装饰器中,这将产生一个干净可行的解决方案:

def with_wand(fn):
    def wrapper(self):
        if not self.wand:
            await self.acquire_wand()
        fn(self)
    return wrapper

@with_wand
async def perform_spell(self):
        self.wand.wave()

尚未测试代码,请告诉我们它是否有效

将需要
self.wand
的函数包装在装饰器中,这将产生一个干净可行的解决方案:

def with_wand(fn):
    def wrapper(self):
        if not self.wand:
            await self.acquire_wand()
        fn(self)
    return wrapper

@with_wand
async def perform_spell(self):
        self.wand.wave()

尚未测试代码,请告诉我们它是否有效

似乎使用以下方法是解决此问题的最佳方法

class Wizard:
    def __init__(self):
        self.wand = None

    async def learn(self):
        self.wand = await magic()

    async def perform_spell(self):
        if self.wand is None:
            raise Exception("You must first learn to use a wand!")
        self.wand.wave()

似乎使用以下方法是解决此问题的最佳方法

class Wizard:
    def __init__(self):
        self.wand = None

    async def learn(self):
        self.wand = await magic()

    async def perform_spell(self):
        if self.wand is None:
            raise Exception("You must first learn to use a wand!")
        self.wand.wave()

从技术上讲,覆盖
\uuuuu new\uuuu
方法有一个技巧:

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
有关完整示例,请参见代码


但我强烈反对这种方法:在构造函数中使用I/O通常是一个坏主意,请仔细考虑。

从技术上讲,重写
\uuu new\uu
方法有一个技巧:

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
有关完整示例,请参见代码



但我强烈反对这种方法:在构造函数中使用I/O通常是个坏主意,请考虑一下。

我想你已经得到了你的建议,但我想质疑你的前提。谁告诉你这是“坏蟒蛇”?我总是给我的对象属性,每当我需要它们来记住一些东西的时候。他们有一个理由。Python不是Java。

我想你得到了你的建议,但我想质疑你的前提。谁告诉你这是“坏蟒蛇”?我总是给我的对象属性,每当我需要它们来记住一些东西的时候。他们有一个理由。Python不是Java。

这是可行的,但如果我有多个属性(
wand
clope
hat
,和
rabbit
),它会很快变得混乱。这也可能意味着,对于我在函数中使用的每个属性,我都需要一个
@decorator
,这看起来仍然很笨拙。@2Cubed您可以有一个decorator,它接受可选参数并检查所有这些
属性是否存在!贾汉吉尔:没错。但这看起来仍然是一种混乱的方式——我不希望在类中的每个函数上都使用相同的修饰符。然后我建议您尝试使用此模块,使
异步函数成为同步函数:Jahangir:我不能这样做。我所做的工作要求我的代码是异步的。这是可行的,但如果我有多个属性(
wand
clope
hat
、以及
rabbit
),它会很快变得混乱。这也可能意味着,对于我在函数中使用的每个属性,我都需要一个
@decorator
,这看起来仍然很笨拙。@2Cubed您可以有一个decorator,它接受可选参数并检查所有这些
属性是否存在!贾汉吉尔:没错。但这看起来仍然是一种混乱的方式——我不希望在类中的每个函数上都使用相同的修饰符。然后我建议您尝试使用此模块,使
异步函数成为同步函数:Jahangir:我不能这样做。我所做的工作要求我的代码是异步的。通常认为不在
\uuuu init\uuuu
中定义属性是糟糕的Python。如果您(或您的类的用户)决定访问属性
self.wand
,它将引发一个
AttributeError
,这不是“好”。您是否有一个“一般认为不好”的参考??我以前没有见过它,除了在写一些人认为Python只是Java变体的文章时。当然,如果你没有魔杖,你将无法访问self.wand,就像如果你没有船,你无法访问self.boat一样。重点是什么<代码>\uuuu init\uuuu
与此无关。如果你想知道一个对象有什么属性,可以使用dir(或者用编程的方式,使用hasattr/getattr),啊,好吧,我有点误解你了。那么.魔杖是类向导界面的一部分吗?也就是说,所有的巫师都保证有魔杖?(我知道一个向导可以明智地没有魔杖。)那么你的问题是标准的“我想要等待的X,但Python让我只有等待的Y”-你的X是“对象初始化”,Y是“迭代、上下文管理器或普通函数/方法”。虽然可以编写可等待的对象初始化(如@Andrew Svetlov所示),但更普通的解决方案是只使用Ys中的一个:编写自己的工厂。通常认为不在
\uuu init\uuu
中定义属性是糟糕的Python。如果您(或您的类的用户)决定访问属性
self.wand
,它将引发一个
AttributeError
,这不是“好”。您是否有一个“一般认为不好”的参考??我以前没有见过它,除了在写一些人认为Python只是Java变体的文章时。当然,如果你没有魔杖,你将无法访问self.wand,就像如果你没有船,你无法访问self.boat一样。重点是什么<代码>\uuuu init\uuuu
与此无关。如果你想知道一个对象有什么属性,可以使用dir(或者用编程的方式,使用hasattr/getattr),啊,好吧,我有点误解你了。那么.魔杖是类向导界面的一部分吗?也就是说,所有的巫师都保证有魔杖?(我知道一个巫师可以明智地不用魔杖。)那么你的问题就是标准