让我们假设我们有一个带有只能异步设置的属性的类。有没有一种方法可以在不显式调用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和setters进行异步操作。我错过了什么?

最佳答案

您不能将一个语句嵌套在另一个语句中。分配是一个语句,await也是。您可以使用setattr()在表达式中设置属性:

await setattr(t, 'attrib', 3)

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

09-12 03:23