Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
878 views
in Technique[技术] by (71.8m points)

python - Setting a descriptor in python3.5 asynchronously

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()

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

How would I set this attribute?

  • 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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

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.

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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...