Заставить UserString вести себя как strPython

Программы на Python
Ответить
Anonymous
 Заставить UserString вести себя как str

Сообщение Anonymous »

TLDR; есть ли способ заставить UserString приниматься как str или определить класс, который наследуется от str, а затем перехватывать доступ к self в str (чтобы изменить его перед возвратом)?

Мы хотим автоматически применять функцию к определенным строкам. Функцию следует применять лениво (т. е. когда строка используется/читается). В нашем случае это перевод с помощью gettext, но это может быть любая функция.
Подобные классы существуют, например. в py-babel LazyProx.
Мы используем встроенную в Python UserString для применения функции следующим образом:

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

class LazyString(UserString):

def __init__(self, original_str: str):
self.original_str = original_str

@property
def data(self) -> str:
return our_func(self.original_str)
Наша проблема заключается в том, что этот подход работает везде, где мы ожидаем строку (изначально или после вызова str() для объекта), но во многих местах UserStrings не принимаются как тип str. Основные проблемы:
  • Средство записи файлов по умолчанию выполняет вызов isinstance(...,str) перед записью строки.
  • json.dumps не принимает UserString в качестве ключей (даже если это просто str)
  • pydantic очень... педантичен в отношении типов, о которых он предупреждает в UserString, где str ожидается, но также терпит неудачу при сериализации и дампе модели.
Мы обошли большинство этих проблем, расширив наш класс или набрав тип, но это «кажется неправильным», потому что.... UserString — это просто строка....
Мы также не можем наследовать от str, потому что это обходит нашу ленивую функцию и просто возвращает строку. Итак, вопрос в том, есть ли способ перехватить доступ к себе в строке или есть способ заставить UserString приниматься как строка (поскольку она равна во всех практических терминах)?
Edit/Addition
Во время исследования мы обнаружили больше связанных тем:
https://github.com/python/typeshed/issues/5957 объясняет, почему типизация UserString и str различна, и почему потребовалось бы много усилий, чтобы сделать их равными (т. е. в соответствии с типом StringLike).
https://github.com/django/django/blob/a ... __.py#L111 показывает, как Django решает проблему, хотя в результате получается выделенный класс, а не строка вообще
https://github.com/python-babel/flask-babel Flask-babel также имеет ленивую строку, но это не строка
Ответить

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

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

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

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

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