我可以写一个描述符,返回一个可以等待的未来。
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。
value=await device.attr
如何设置此属性?
await device.attr=5
await setattr(device, 'attr', 5)
device.attr=5
您尝试执行的操作是不可能的(使用Python 3.5)。
虽然__get__返回Future是明智的__set__,但Python 3.5完全不支持进行异步。__set__Python会忽略的返回值,因为没有赋值的“返回值”。且呼叫__set__始终是同步的。就像您已经注意到的那样,a = (b.c = 5)实际上会引发a SyntaxError。
__get__
__set__
a = (b.c = 5)
SyntaxError
如果await device.attr = 5允许类似异步分配,那么异步描述符可能会有一个单独的协议,即协程,__aget__并__aset__作为类似于异步上下文管理器(async with/ __aenter__)和异步迭代(async for/ __aiter__)的特殊方法。有关/支持背后的设计决策,请参见PEP 492。async``await
await device.attr = 5
__aget__
__aset__
async with
__aenter__
async for
__aiter__
async``await
还要注意,__get__归还未来不会产生__get__协程。
没有更多上下文,您似乎希望在描述符协议提供的属性访问抽象后面隐藏某些内容,最好将其明确地完成,但这当然取决于您。