Asyncio:当我们需要使用异步方法时,如何在 __del__ 方法中清理 class 的实例
Asyncio: How to cleanup instance of class in __del__ method when we need to use async methods
假设一个 class 需要一个异步协程来清理:
import asyncio
class AsyncClient:
async def do_something(self):
print ('Doing something')
await asyncio.sleep(1)
print ('Something done')
async def cleanup(self):
print ('Starting cleanup')
await asyncio.sleep(1)
print ('Cleanup in progress 1/3')
await asyncio.sleep(1)
print ('Cleanup in progress 2/3')
await asyncio.sleep(1)
print ('Cleanup in progress 3/3')
def __del__(self):
**CODE_HERE_SHOULD_CALL_CLEANUP**
不允许在 dunder 方法中使用 await。
我应该在 __del__
方法中放入什么以允许在这两种情况下进行清理:
client = AsyncClient()
async def main():
await client.do_something()
asyncio.run(main())
或
async def main():
client = AsyncClient()
await client.do_something()
asyncio.run(main())
我尝试执行以下操作,它适用于第一种情况但不适用于第二种情况(如果循环不再存在,我将重新创建一个循环):
def __del__(self):
print ('__del__()')
try:
loop = asyncio.get_event_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
asyncio.run(self.cleanup())
return
cleanup_task = loop.create_task(self.cleanup())
清理不应取决于何时(或是否)调用 __del__
。定义一个清理方法,然后显式调用它或让上下文管理器为您隐式调用它。
import asyncio
class AsyncClient:
async def do_something(self):
print ('Doing something')
await asyncio.sleep(1)
print ('Something done')
async def cleanup(self):
print ('Starting cleanup')
await asyncio.sleep(1)
print ('Cleanup in progress 1/3')
await asyncio.sleep(1)
print ('Cleanup in progress 2/3')
await asyncio.sleep(1)
print ('Cleanup in progress 3/3')
async def __aenter__(self):
return self
async def __aexit__(self, *args):
await self.cleanup()
然后
client = AsyncClient()
async def main():
await client.do_something()
await client.cleanup()
asyncio.run(main())
或类似
client = AsyncClient()
async def main():
async with client:
await client.do_something()
asyncio.run(main())
假设一个 class 需要一个异步协程来清理:
import asyncio
class AsyncClient:
async def do_something(self):
print ('Doing something')
await asyncio.sleep(1)
print ('Something done')
async def cleanup(self):
print ('Starting cleanup')
await asyncio.sleep(1)
print ('Cleanup in progress 1/3')
await asyncio.sleep(1)
print ('Cleanup in progress 2/3')
await asyncio.sleep(1)
print ('Cleanup in progress 3/3')
def __del__(self):
**CODE_HERE_SHOULD_CALL_CLEANUP**
不允许在 dunder 方法中使用 await。
我应该在 __del__
方法中放入什么以允许在这两种情况下进行清理:
client = AsyncClient()
async def main():
await client.do_something()
asyncio.run(main())
或
async def main():
client = AsyncClient()
await client.do_something()
asyncio.run(main())
我尝试执行以下操作,它适用于第一种情况但不适用于第二种情况(如果循环不再存在,我将重新创建一个循环):
def __del__(self):
print ('__del__()')
try:
loop = asyncio.get_event_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
asyncio.run(self.cleanup())
return
cleanup_task = loop.create_task(self.cleanup())
清理不应取决于何时(或是否)调用 __del__
。定义一个清理方法,然后显式调用它或让上下文管理器为您隐式调用它。
import asyncio
class AsyncClient:
async def do_something(self):
print ('Doing something')
await asyncio.sleep(1)
print ('Something done')
async def cleanup(self):
print ('Starting cleanup')
await asyncio.sleep(1)
print ('Cleanup in progress 1/3')
await asyncio.sleep(1)
print ('Cleanup in progress 2/3')
await asyncio.sleep(1)
print ('Cleanup in progress 3/3')
async def __aenter__(self):
return self
async def __aexit__(self, *args):
await self.cleanup()
然后
client = AsyncClient()
async def main():
await client.do_something()
await client.cleanup()
asyncio.run(main())
或类似
client = AsyncClient()
async def main():
async with client:
await client.do_something()
asyncio.run(main())