Преобразование имен файлов 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'])]
Ответы
Ответ 1
Если вы передадите строку 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'])]
Ответ 2
Я искал решение для 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
Ответ 3
os.walk(unicode(root_dir, 'utf-8'))
Ответ 4
более прямым способом может быть попытка выполнить следующее: найти кодировку файловой системы и затем преобразовать ее в unicode. например,
unicode_name = unicode(filename, "utf-8", errors="ignore")
чтобы перейти в другую сторону,
unicode_name.encode("utf-8")
Ответ 5
os.walk
не указывается, чтобы всегда использовать os.listdir
, но также не указано, как обрабатывается Unicode. Однако os.listdir
говорит:
Изменено в версии 2.3: В Windows NT/2k/XP и Unix, если путь Unicode-объект, результатом будет список объектов Unicode. Undecodable имена файлов будут по-прежнему возвращаться как Строковые объекты.
Использует ли просто аргумент Unicode для вас?
for dirpath, dirnames, filenames in os.walk(u"."):
print dirpath
for fn in filenames:
print " ", fn
Ответ 6
Нет, они не закодированы во внутреннем строчном представлении Pythons, такой вещи нет. Они кодируются в кодировке операционной системы/файловой системы. Однако в unicode работает для os.walk.
Я не знаю, как os.walk ведет себя, когда имена файлов не могут быть декодированы, но я предполагаю, что вы получите строку обратно, например, с os.listdir(). В этом случае у вас снова будут проблемы. Кроме того, не вся стандартная библиотека Python 2.x будет правильно принимать параметры Юникода, поэтому вам может понадобиться кодировать их как строки в любом случае. Таким образом, проблема может быть в другом месте, но вы заметите, что это так.; -)
Если вам нужно больше контролировать декодирование, вы не можете всегда передавать строку, а затем просто декодировать ее с помощью filename = filename.decode()
как обычно.