В Linux имена файлов «всего лишь пучок байтов» и не обязательно кодируются в конкретной кодировке. Python 3 пытается превратить все в строки Unicode. При этом разработчики разработали схему для перевода байтовых строк в строки Unicode и обратно без потерь и без знания исходной кодировки. Они использовали частичные суррогаты для кодирования «плохих» байтов, но обычный кодер UTF8 не может обрабатывать их при печати на терминал.
Например, вот не-UTF8 байт строки:
>>> b'C\xc3N'.decode('utf8','surrogateescape')
'C\udcc3N'
Это могут быть преобразованы в и из Unicode без потерь:
>>> b'C\xc3N'.decode('utf8','surrogateescape').encode('utf8','surrogateescape')
b'C\xc3N'
Но это не может быть напечатано:
>>> print(b'C\xc3N'.decode('utf8','surrogateescape'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'utf-8' codec can't encode character '\udcc3' in position 1: surrogates not allowed
Вам нужно будет выяснить, что вы хотите делать с именами файлов с кодировками по умолчанию. Возможно, просто перекодируйте их обратно в исходные байты и декодируйте их с неизвестной заменой. Используйте это для отображения, но сохраните исходное имя для доступа к файлу.
>>> b'C\xc3N'.decode('utf8','replace')
C�N
os.walk
также может принимать строку байтов и будет возвращать байт строки вместо строк Unicode:
for p,d,f in os.walk(b'.'):
Затем вы можете расшифровать, как вам нравится.
, выпуск питона 3? –
Python 3.4.0 (по умолчанию, 11 апреля 2014, 13:05:11) на Ubuntu 14.04. У меня есть «LANG = en_US.UTF-8' –
« print (root.encode («utf-8», «surrogateescape»)) 'имеет какой-то эффект? –