await setattr(device,'attr',5) construct is also possible and actually more decent than device.attr = 5, but don't overload the genuine setattr of course.
this one is actually usefull for async threadless while keeping easy readability. running code that set value without await will raise a nice "RuntimeWarning: coroutine attr.__set__
was never awaited"
import asyncio, sys
async def main():
obj.attr = "not async value"
print(obj.attr)
print()
print("now give set an async value")
#DO NOT DO THAT use aio.asetattr(obj,'attr',5)
setattr = aio.asetattr
# ============== yes i can, thanks python ! ===========
await setattr(obj,'attr',5)
# ======================================
print(obj.attr)
print("bye")
flush_io()
def flush_io():
sys.stdout.flush()
sys.stderr.flush()
class attr:
def __init__(self, value):
self.value = value
def __get__(self, obj, objtype):
if obj is None:
return self
return self.value
async def __set__(self, obj, value):
if value is not obj.__class__:
print(" async updating", self, end=" ")
for i in range(value):
await asyncio.sleep(1)
print(".", end="")
flush_io()
print()
self.value = value
print("set", obj, value)
return
print("__set__", obj, value)
def __repr__(self):
return "<async attr>"
class aobj:
attr = attr("empty")
def __repr__(self):
return "<aobj>"
class aio:
async def asetattr(self, obj, attr, value):
await asyncio.sleep(1)
a_attr = getattr( type(obj), attr)
await a_attr.__set__(obj, value)
print("done!")
aio = aio()
obj = aobj()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
__set__
shouldn't be returning anything. Did you wantvalue
to be resolved asynchronously? – Friedcake