异步属性设置器

时间:2016-04-16 15:36:37

标签: 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()

失败
  File "asyncprop.py", line 22
    await t.attrib = 3
       ^
SyntaxError: can't assign to await expression

这并不奇怪,因为await的语法是

await ::=  ["await"] primary

所以看起来我们一定会忘记这个不错的@property并且让我们自己使用getter和setter进行异步操作。我错过了什么吗?

2 个答案:

答案 0 :(得分:8)

你不能在另一个陈述中嵌套一个陈述;赋值是一个陈述,await也是。您可以使用setattr()在表达式中设置属性:

await setattr(t, 'attrib', 3)

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

答案 1 :(得分:0)

您可以使用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