Я хотел бы добавить некоторую информацию о классе UserString
.
Python встроенные типы, такие как str
, на самом деле не являются реальными Python классами, но C конструкции (при условии стандартной реализации Python, CPython). Это помогает с быстротой и, вероятно, с совместимостью Python - C, но поведение встроенных модулей может отличаться от обычного пользовательского класса. Существуют случаи, когда эта деталь реализации имеет значение.
Это пример такой ситуации. Возможно, механизм регулярных выражений re
написан на C и работает с C строками. UserString
"имитирует строковый объект" , но это не один.
Кажется, что все подпрограммы C не работают с UserString
. Например, вы не можете запустить importlib
, subprocess
или os.path
для этого класса. В 2001 году было предложение по улучшению . Но исправление не было реализовано, потому что не существует простого способа сделать это.
Следовательно, стандартного способа его исправить не существует. Вам нужно использовать какой-то обходной путь: либо .data
, как в ответе Чепнера, либо как в связанном вопросе, сделайте str(UserString('foo'))
.
Кроме того, сообщение об ошибке
TypeError: expected string or bytes-like object
на самом деле означает, что ему нужен str
объект. По умолчанию «строка» означает str
в Python. Что может сбивать с толку в случае «строковых» объектов и т. Д. c.
Наконец, в моем реальном случае использования мне пришлось использовать строковый класс MyString
, который можно расширить с новыми методами в будущем. В настоящее время я просто использовал MyString = str
и думал, что он будет легко расширяться в будущем, когда возникнет необходимость.
Необходимость пришла, я определил class MyString(UserString)
, и мои тесты сказали мне, что им нужно строка. Теперь, немного неловко и не Pythoni c, половина моего кода обрабатывает MyString
как строку, а другая половина - MyString('foo').data
. И что еще хуже, этот класс MyString
является частью интерфейса одного из модулей. Таким образом, пользователь должен знать подробности реализации интерфейса модуля ...
В моем случае кажется, что я могу кодировать эту проблему. Но это требует некоторого переписывания всего модуля. Так что, вероятно, функция, реализованная в UserString
, не стоит усилий прямо сейчас.