Преобразование имен файлов 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() как обычно.