Вызовите асин c функцию / свойство внутри __str__ - PullRequest
1 голос
/ 14 марта 2020

Итак, я пытаюсь перенести код для работы с 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).

...