异步属性设置器

Evp*_*pok 6 python async-await

让我们假设我们有一个具有只能异步设置的属性的类.有没有办法在没有明确调用setter的情况下完成这项工作?

MNWE:

import asyncio

loop = asyncio.get_event_loop()

class AsyncTest:
    def __init__(self, attrib):
        self._attrib = attrib

    @property
    def attrib(self):
        return self._attrib

    @attrib.setter
    async def set_attrib(self, attrib):
        await asyncio.sleep(1.0)
        self._attrib = attrib


async def main():
    t = AsyncTest(1)
    print(t.attrib)
    await t.attrib = 3
    print(t.attrib)

asyncio.ensure_future(main())
loop.run_forever()
Run Code Online (Sandbox Code Playgroud)

这失败了

  File "asyncprop.py", line 22
    await t.attrib = 3
       ^
SyntaxError: can't assign to await expression
Run Code Online (Sandbox Code Playgroud)

这并不奇怪,因为语法await

await ::=  ["await"] primary
Run Code Online (Sandbox Code Playgroud)

因此,似乎我们必然会忘记这一点@property并且让我们自己使用getter和setter进行异步操作.我错过了什么?

Mar*_*ers 10

您不能将语句嵌套在另一个语句中; 赋值是一种陈述,同样如此await.您可以使用setattr()在表达式中设置属性:

await setattr(t, 'attrib', 3)
Run Code Online (Sandbox Code Playgroud)

但是,以property不支持async方法的方式包装setter (它们不等待),所以使用显式setter方法仍然会更好.

  • 是的,但它仍然只能通过`setattr`工作,这种方式会破坏拥有财产的目的. (2认同)

小智 7

您可以使用该async-property包:https : //pypi.org/project/async-property/

例子:

from async_property import async_property

class Foo:
    @async_property
    async def remote_value(self):
        return await get_remote_value()

f = Foo()
await f.remote_value
Run Code Online (Sandbox Code Playgroud)

  • 注意:从 async-property 0.2.1 开始,它不支持 setter。 (4认同)