在python3.5中异步设置描述符 [英] Setting a descriptor in python3.5 asynchronously

查看:61
本文介绍了在python3.5中异步设置描述符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I can write a descriptor returning a future which could be awaited on.

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 在协程中获取值.

Now I can get the value in a coroutine with value=await device.attr.

我将如何设置此属性?

  • await device.attr=5 -> 语法错误:无法分配给 await 表达式
  • await setattr(device, 'attr', 5) -> TypeError: object NoneType 不能用于 'await' 表达式
  • device.attr=5 -> RuntimeWarning:协程__set__"从未被等待
  • await device.attr=5 -> SyntaxError: can't assign to await expression
  • await setattr(device, 'attr', 5) -> TypeError: object NoneType can't be used in 'await' expression
  • device.attr=5 -> RuntimeWarning: coroutine '__set__' was never awaited

推荐答案

您尝试做的事情是不可能的(使用 Python 3.5).

What you are trying to do is not possible (with Python 3.5).

虽然 __get__ 返回 Future 可能是明智的,但 Python 3.5 根本不支持使 __set__ 异步.__set__ 的返回值被 Python 忽略,因为没有赋值的返回值".并且对 __set__ 的调用始终是同步的.正如您已经注意到的那样,a = (b.c = 5) 实际上会引发 SyntaxError.

While it may be sensible for __get__ to return a Future, making __set__ async is simply not supported by Python 3.5. The return value of __set__ is ignored by Python since there is no "return value" of assignments. And the call to __set__ is always synchronous. Something like a = (b.c = 5) actually raises a SyntaxError as you already noticed.

如果允许像 await device.attr = 5 这样的异步赋值,那么异步描述符可能会有一个单独的协议,即协程 __aget____aset__ 作为特殊方法,类似于异步上下文管理器(async with/__aenter__ )和异步迭代(async for/__aiter__).有关 asyncPEP 492>/await 支持.

If async assignments like await device.attr = 5 were allowed, there would probably be a separate protocol for async descriptors, i.e. with coroutines __aget__ and __aset__ as special methods in analogy to async context manager (async with / __aenter__ ) and async iteration (async for / __aiter__). See PEP 492 for the design decisions behind the async / await support.

还要注意 __get__ 返回一个 future 不会使 __get__ 成为一个协程.

Also note that __get__ returning a future does not make __get__ a coroutine.

如果没有进一步的上下文,您似乎想在描述符协议提供的属性访问抽象背后隐藏一些东西,最好明确地完成,但这当然取决于您.

Without further context, it looks like you want to hide something behind the attribute access abstraction provided by the descriptor protocol which should better be done explicitly, but that's up to you of course.

这篇关于在python3.5中异步设置描述符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆