一尘不染

异步在python3.5中设置描述符

python

我可以写一个描述符,返回一个可以等待的未来。

class AsyncDescriptor:
    def __get__(self, obj, cls=None):
         # generate some async future here
         return future

    def __set__(self, obj, value):
         # generate some async future here
         return future

class Device:
    attr=AsyncDescriptor()

device=Device()

现在,我可以用来获取协程中的值value=await device.attr

如何设置此属性?

  • await device.attr=5 -> SyntaxError:无法分配给等待表达式
  • await setattr(device, 'attr', 5) -> TypeError:对象NoneType不能在’await’表达式中使用
  • device.attr=5 -> RuntimeWarning:从未等待协程’set

阅读 179

收藏
2021-01-20

共1个答案

一尘不染

您尝试执行的操作是不可能的(使用Python 3.5)。

虽然__get__返回Future是明智的__set__,但Python
3.5完全不支持进行异步。__set__Python会忽略的返回值,因为没有赋值的“返回值”。且呼叫__set__始终是同步的。就像您已经注意到的那样,a = (b.c = 5)实际上会引发a SyntaxError

如果await device.attr = 5允许类似异步分配,那么异步描述符可能会有一个单独的协议,即协程,__aget____aset__作为类似于异步上下文管理器(async with/ __aenter__)和异步迭代(async for/ __aiter__)的特殊方法。有关/支持背后的设计决策,请参见PEP
492
async``await

还要注意,__get__归还未来不会产生__get__协程。

没有更多上下文,您似乎希望在描述符协议提供的属性访问抽象后面隐藏某些内容,最好将其明确地完成,但这当然取决于您。

2021-01-20