Преобразование имен файлов Python в Unicode
Я на Python 2.6 для Windows.
Я использую os.walk для чтения файлового дерева. Файлы могут содержать не 7-битные символы (например, немецкое "ae") в именах файлов. Они закодированы во внутреннем строковом представлении Pythons.
Я обрабатываю эти имена файлов с помощью функций библиотеки Python, и это не удается из-за неправильной кодировки.
Как я могу преобразовать эти имена файлов в правильные (Unicode?) Строки Python?
У меня есть файл "d:\utest\ü.txt". Передача пути как Unicode не работает:
>>> list(os.walk('d:\\utest'))
[('d:\\utest', [], ['\xfc.txt'])]
>>> list(os.walk(u'd:\\utest'))
[(u'd:\\utest', [], [u'\xfc.txt'])]
6 ответов
Если вы передаете строку Unicode os.walk()
, вы получите результаты Unicode:
>>> list(os.walk(r'C:\example')) # Passing an ASCII string
[('C:\\example', [], ['file.txt'])]
>>>
>>> list(os.walk(ur'C:\example')) # Passing a Unicode string
[(u'C:\\example', [], [u'file.txt'])]
Я искал решение для Python 3.0+. Поставит это здесь, если это кому-то еще нужно.
rootdir = r'D:\COUNTRY\ROADS\'
fs_enc = sys.getfilesystemencoding()
for (root, dirname, filename) in os.walk(rootdir.encode(fs_enc)):
# do your stuff here, but remember that now
# root, dirname, filename are represented as bytearrays
Более прямым способом может быть попытка сделать следующее: найти кодировку вашей файловой системы, а затем преобразовать ее в Unicode. например,
unicode_name = unicode(filename, "utf-8", errors="ignore")
пойти другим путем,
unicode_name.encode("utf-8")
os.walk
не указано, чтобы всегда использовать os.listdir
, но также не указано, как обрабатывается Unicode. Тем не мение, os.listdir
говорит:
Изменено в версии 2.3: В Windows NT/2k/XP и Unix, если путь - это объект Unicode, результатом будет список объектов Unicode. Не декодируемые имена файлов будут по-прежнему возвращаться как строковые объекты.
Работает ли просто использование аргумента Unicode для вас?
for dirpath, dirnames, filenames in os.walk(u"."):
print dirpath
for fn in filenames:
print " ", fn
Нет, они не закодированы во внутреннем строковом представлении Pythons, такого нет. Они кодируются в кодировке операционной системы / файловой системы. Переход на Unicode работает для Os.Walk, хотя.
Я не знаю, как ведет себя os.walk, когда имена файлов не могут быть декодированы, но я предполагаю, что вы получите строку обратно, как с os.listdir(). В этом случае у вас снова будут проблемы позже. Кроме того, не вся стандартная библиотека Python 2.x будет правильно принимать параметры Юникода, поэтому вам может понадобиться закодировать их как строки в любом случае. Таким образом, проблема на самом деле может быть где-то еще, но вы заметите, если это так.;-)
Если вам нужно больше контроля над декодированием, вы не всегда можете передать строку, а затем просто расшифруйте ее с именем файла = filename.decode() как обычно.