Я бы очень хотел, чтобы мое приложение на Python работало исключительно со строками Unicode. В последнее время у меня все шло хорошо, но я столкнулся с проблемой обработки путей. POSIX API для файловых систем не является Unicode, поэтому файлы могут иметь (и на самом деле довольно распространенные) имена с «не декодируемыми» именами: имена файлов, которые не закодированы в указанной кодировке файловой системы.
В Python это проявляется как смесь unicode
и str
объектов, возвращаемых из os.listdir()
.
>>> os.listdir(u'/path/to/foo')
[u'bar', 'b\xe1z']
В этом примере символ '\xe1'
закодирован в Latin-1 или в некотором роде, даже когда (гипотетическая) файловая система сообщает sys.getfilesystemencoding() == 'UTF-8'
(в UTF-8 этот символ будет двумя байтами '\xc3\xa1'
). По этой причине вы получите UnicodeError
s повсюду, если попытаетесь использовать, например, os.path.join()
с путями Unicode, потому что имя файла не может быть декодировано.
Python Unicode HOWTO предлагает этот совет о путевых именах Unicode:
Обратите внимание, что в большинстве случаев следует использовать API-интерфейсы Unicode. API байтов следует использовать только в системах, где могут присутствовать некодируемые имена файлов, то есть в системах Unix.
Поскольку я в основном беспокоюсь о системах Unix, означает ли это, что я должен реструктурировать свою программу, чтобы иметь дело только с байтовыми строками для путей? (Если так, как я могу поддерживать совместимость с Windows?) Или есть другие, более эффективные способы работы с некодируемыми именами файлов? Являются ли они достаточно редкими «в дикой природе», чтобы я просто попросил пользователей переименовать их проклятые файлы?
(Если лучше иметь дело только с внутренними строками, у меня возник вопрос: как хранить строки байтов в SQLite для одного столбца, сохраняя остальные данные в виде дружественных строк Юникода?)