Закрытие aiohttp.ClientSession при уничтожении родительского объекта - PullRequest
0 голосов
/ 27 сентября 2018

Я пишу CLI для доступа к REST API.Я определил aiohttp.ClientSession поле класса _client_session в асинхронном методе инициализации.

Как правильно закрыть aiohttp.ClientSession?Если я сделаю:

import asyncio
import aiohttp


class Profile:                                                                    
    def __init__(self, loop):                                                     
        self._loop = loop                                                         
        self._client_session = None                                               

    def __del__(self):                                                            
        self._loop.run_until_complete(self._client_session.close())              

    async def async_init(self):
        self._client_session = aiohttp.ClientSession()                           

    @classmethod
    async def create(cls, loop):
        self = cls(loop)
        await self.async_init()
        return self


loop = asyncio.get_event_loop()
profile = loop.run_until_complete(Profile.create(loop))                          
loop.close()

Я получу это:

Exception ignored in: <bound method Profile.__del__ of <profile.Profile object at 0x7f8ab82e15c0>>
Traceback (most recent call last):
File "/home/rominf/projects/profile/profile/__init__.py", line 197, in __del__
File "/home/rominf/.pyenv/versions/3.6.6/lib/python3.6/asyncio/base_events.py", line 444, in run_until_complete
File "/home/rominf/.pyenv/versions/3.6.6/lib/python3.6/asyncio/base_events.py", line 358, in _check_closed
RuntimeError: Event loop is closed
sys:1: RuntimeWarning: coroutine 'ClientSession.close' was never awaited
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7f8ab43bf588>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x7f8ab28a06a8>, 11519.944147989)]']
connector: <aiohttp.connector.TCPConnector object at 0x7f8ab43bf3c8>

Я понимаю, что это происходит по причине: я закрываю loop до того, как сборщик мусора удалит profile.Решение состоит в том, чтобы удалить его вручную с помощью del, но я не хочу этого делать.

Есть ли способ зарегистрировать будущее для выполнения непосредственно перед закрытием цикла события?

1 Ответ

0 голосов
/ 27 сентября 2018

asyncio не поддерживает ввод-вывод в деструкторах.То же самое для конструкторов и свойств.

Рекомендуемый способ добавления поддержки async with Profile или await profile.close().

...