Объект с задачей asyncio не уничтожается, когда выходит за рамкиPython

Программы на Python
Ответить
Anonymous
 Объект с задачей asyncio не уничтожается, когда выходит за рамки

Сообщение Anonymous »

Я заметил, что объекты, включающие задачу asyncio Task, не удаляются, когда они выходят за пределы области действия, и мне хотелось бы узнать, как лучше управлять этими объектами, чтобы избегайте накопления слишком большого количества.
Пример:

Код: Выделить всё

import asyncio

class BackgroundTask:
def __init__(self):
self.task = asyncio.create_task(self.heartbeat()) # line to remove
pass

async def heartbeat(self):
while True:
await asyncio.sleep(1)
print("^")

def __del__(self):
print("bar deleted")

async def foo():
bar = BackgroundTask()
await asyncio.sleep(2)
bar.task.cancel() # line to remove

async def main():
await foo()
print("foo has ended")
await asyncio.sleep(2)
print("main ended")

asyncio.run(main())
Когда я запускаю это, я получаю:

Код: Выделить всё

^
foo has ended
main ended
bar deleted
т.е. объект bar не удаляется до конца цикла событий, а не сразу после того, как foo заканчивается и выходит за пределы области действия.
Если вы прокомментируете из двух отмеченных строк (т. е. удалил задачу), то я получаю ожидаемое поведение - объект удаляется непосредственно перед тем, как foo возвращается в основной

Код: Выделить всё

bar deleted
foo has ended
main ended
Если foo вызывался неоднократно, будут ли эти объекты накапливаться, пока не начнут вызывать проблемы? например, если main() был переопределен как:

Код: Выделить всё

async def main():
while True:
await foo()
print("foo has ended")
await asyncio.sleep(2)
Есть ли способ гарантировать, что такой объект будет удален, когда он выходит за пределы области действия, кроме ручного управления количеством созданных объектов?
На самом деле это так. для приложения MicroPython, поэтому, если есть какая-либо разница в ответе для MicroPython, я хотел бы знать. (Для этой демонстрации я использовал CPython, поскольку в MicroPython нет специального метода __del__())

Подробнее здесь: https://stackoverflow.com/questions/792 ... t-of-scope
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»