I'm trying to create a sort of timer callback to a bound async
method using asyncio
's event loop. The problem now is that the bound async method should not hold a strong reference to the instance, otherwise the latter will never be deleted. The timer callback should only live as long as the parent instance.
I've found a solution, but I don't think it's pretty:
import asyncio
import functools
import weakref
class ClassWithTimer:
def __init__(self):
asyncio.ensure_future(
functools.partial(
ClassWithTimer.update, weakref.ref(self)
)()
)
def __del__(self):
print("deleted ClassWithTimer!")
async def update(self):
while True:
await asyncio.sleep(1)
if self() is None: break
print("IN update of object " + repr(self()))
async def run():
foo = ClassWithTimer()
await asyncio.sleep(5)
del foo
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
Is there a better, more pythonic way to do this? The timer callback really needs to be async.
Without asyncio
, weakref.WeakMethod
would probably be the way to go. But asyncio.ensure_future
requires a coroutine object, so it won't work in this case.