当前位置: 首页 > 面试题库 >

如何在__init__中设置带有等待的类属性

佴波鸿
2023-03-14
问题内容

如何await在构造函数或类主体中定义类?

例如我想要的:

import asyncio

# some code


class Foo(object):

    async def __init__(self, settings):
        self.settings = settings
        self.pool = await create_pool(dsn)

foo = Foo(settings)
# it raises:
# TypeError: __init__() should return None, not 'coroutine'

或具有类body属性的示例:

class Foo(object):

    self.pool = await create_pool(dsn)  # Sure it raises syntax Error

    def __init__(self, settings):
        self.settings = settings

foo = Foo(settings)

我的解决方案(但我希望看到更优雅的方式)

class Foo(object):

    def __init__(self, settings):
        self.settings = settings

    async def init(self):
        self.pool = await create_pool(dsn)

foo = Foo(settings)
await foo.init()

问题答案:

最神奇的方法不旨在与工作async def/ await-在一般情况下,你应该只使用await专用异步魔术方法里面-
__aiter____anext____aenter____aexit__。在其他魔术方法中使用它或者根本无法正常工作__init__(除非您使用此处其他答案中描述的一些技巧),否则将迫使您始终在异步上下文中使用任何触发魔术方法调用的方法。

现有的asyncio库通常以以下两种方式之一来处理此问题:首先,我已经看到了使用的工厂模式(asyncio- redis例如):

import asyncio

dsn = "..."

class Foo(object):
    @classmethod
    async def create(cls, settings):
        self = Foo()
        self.settings = settings
        self.pool = await create_pool(dsn)
        return self

async def main(settings):
    settings = "..."
    foo = await Foo.create(settings)

其他库使用创建对象的顶级协程函数,而不是工厂方法:

import asyncio

dsn = "..."

async def create_foo(settings):
    foo = Foo(settings)
    await foo._init()
    return foo

class Foo(object):
    def __init__(self, settings):
        self.settings = settings

    async def _init(self):
        self.pool = await create_pool(dsn)

async def main():
    settings = "..."
    foo = await create_foo(settings)

create_pool要从aiopg中调用的函数__init__实际上正在使用此确切模式。

这至少解决了这个__init__问题。我还没有看到可以在野外进行异步调用的类变量,所以我不知道会出现任何完善的模式。



 类似资料:
  • 我在Rails应用程序上使用gem。 想设置一个列表属性,但在swagger官方数据类型中没有找到: https://swagger.io/docs/specification/data-models/data-types/ 字符串 数 整数 布尔 数组 对象 例如,响应数据将是: 尝试过: 这是字符串。

  • 我有以下课程 < li >抽象类duck 此类具有< code>flyBehavoir类型的< code>FlyBehavoir 函数,以执行flying < code > preformFly() < br >函数来设置< code > flyBehavoir < code > setFlyBrhavoir(flyBehavoir$flyBehavoir) < li >类DonaldDuck扩展

  • 以下是我Firebase云函数的简化代码: 如上所述,循环中有一个等待表达式,但我有一个错误标记,如下图所示,因此我未能部署该函数: 这是我运行

  • 我尝试编写一个小的.sh来循环并再次启动/bin/bash,但是在我的入口点中使用它会产生一个错误,即它找不到.sh文件,尽管我知道它在容器中。 有什么想法吗?

  • 我如何在log4j2中做到这一点?注我仍然需要使用新的属性文件(不是xml或json)。 TIA

  • Liskov替代原则规定: 子类型中必须保留超类型的不变量。 我对这个原理和多态性的交叉点特别感兴趣。但在特定的子类型多态性中,事实上,参数多态性和Haskell类型类似乎就是这种情况。 所以,我知道函数是子类型,当它们的参数是逆变的,它们的返回类型是协变的。我们可以假设方法只是带有隐式“自我”参数的函数。然而,这似乎意味着如果子类重写父类的方法,它就不再是子类型,因为它的一个方法不再是子类型。