Итак, я пытаюсь перенести код для работы с Asyncio.
Моя проблема - @property
s, которые - если еще не кешированы - требуют завершения сетевого запроса.
Хотя я могу ожидать их без проблем в большинстве контекстов, использование этого свойства в методе __str__
терпит неудачу, что вполне ожидаемо.
Какой самый лучший способ решения этой проблемы pythoni c, кроме кэширования значение при создании экземпляра или просто без использования Asyncio.
Вот пример кода, иллюстрирующего проблему:
import requests
from typing import Union
class Example(object):
_username: Union[str, None]
@property
def username(self):
if not _username:
r = request.get('https://api.example.com/getMe')
self._username = r.json()['username']
return self._username
def __str__(self):
return f"Example(username={self.username!r})"
e = Example()
str(e)
До сих пор я мог придумать следующее.
Я мог бы заменить @property
на @async_property
( PyPi , Github , Docs ) и requests
на httpx
( PyPi , Github , Docs ).
Однако он все еще не работает.
Моя попытка перенести его в Asyncio :
import httpx
from typing import Union
from async_property import async_property
class Example(object):
_username: Union[str, None]
@async_property
async def username(self):
if not _username:
async with httpx.AsyncClient() as client:
r = await client.get('https://www.example.org/')
self._username = r.json()['username']
return self._username
async def __str__(self):
return f"Example(username={await self.username!r})"
e = Example()
str(e)
Сбой с TypeError: __str__ returned non-string (type coroutine)
.