pum*_*aus 7 python weak-references timer python-asyncio
我正在尝试async
使用asyncio
事件循环创建一种对绑定方法的计时器回调.现在的问题是绑定的异步方法不应该保存对实例的强引用,否则后者永远不会被删除.定时器回调应该只与父实例一样长.我找到了一个解决方案,但我认为它并不漂亮:
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())
Run Code Online (Sandbox Code Playgroud)
有没有更好,更pythonic的方式来做到这一点?计时器回调确实需要异步.没有asyncio
,weakref.WeakMethod
可能是要走的路.但是asyncio.ensure_future
需要一个协程对象,所以在这种情况下它不起作用.
根据 Huazuo Gau 和 germn 的答案,我实现ensure_weakly_binding_future
的基本上与绑定方法的实例相同ensure_future
,但没有保留对绑定方法实例的强引用。它不会修改整体绑定(就像基于装饰器的解决方案所做的那样),并在删除父实例时正确取消未来:
import asyncio
import weakref
def ensure_weakly_binding_future(method):
class Canceller:
def __call__(self, proxy):
self.future.cancel()
canceller = Canceller()
proxy_object = weakref.proxy(method.__self__, canceller)
weakly_bound_method = method.__func__.__get__(proxy_object)
future = asyncio.ensure_future(weakly_bound_method())
canceller.future = future
class ClassWithTimer:
def __init__(self):
ensure_weakly_binding_future(self.update)
def __del__(self):
print("deleted ClassWithTimer!", flush=True)
async def update(self):
while True:
await asyncio.sleep(1)
print("IN update of object " + repr(self), flush=True)
async def run():
foo = ClassWithTimer()
await asyncio.sleep(5.5)
del foo
await asyncio.sleep(2.5)
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2002 次 |
最近记录: |