LINUX.ORG.RU

python2 и юникодные пути

 , ,


0

1

Мне нужно получить дерево каталогов в юникоде. Делаю так:

#!/usr/bin/python2
import os
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('path', type=unicode)
args = parser.parse_args()
for (dir, subsdirs, files) in os.walk(args.path):
    for file in files:
        filename = os.path.join(dir, file)
И это не работает, если аргумент path содержит юникодные символы, ругается на invalid unicode value. При этом, если в дереве каталогов есть файлы с именами, содержащими юникод, то всё Ok, проблема только с тем, что передаётся в качестве аргумента. Почему так?

★★★★★

Последнее исправление: Axon (всего исправлений: 1)

Ответ на: комментарий от stevejobs

А так всё Ok, даже без игнора ошибок. Оно, конечно, сойдёт, но хочется понять на будущее где подвох.

Axon ★★★★★
() автор топика
Ответ на: комментарий от Axon

В питоновской стандартной библиотеке, которая иногда работает с юникодом, а иногда не работает, совершенно непредсказуемо

stevejobs ★★★★☆
()
Ответ на: комментарий от stevejobs

Мда, не зря я к третьему питону склоняюсь. Жаль, что автор-фанатик отказывается портировать на него mutagen... Спасибо душевное за помощь.

Axon ★★★★★
() автор топика
Ответ на: комментарий от stevejobs

Не, там не надо ничего никуда encode, там юникод сразу и так. Я сначала свой скрипт на тройке наваял, и там всё работало отлично. Правда, потом оказалось, что либа для работы с тегами, которую я заюзал, хоть и удобная, но местами фейлится. Пришлось переписывать с мутагеном, и, соответственно, править под двойку.

Axon ★★★★★
() автор топика
Последнее исправление: Axon (всего исправлений: 1)
Ответ на: комментарий от Axon

Подвох в том, что твой путь не содержит питоньи юникодные символы, и тип unicode тут не подходит. Нужен str.

Внутренний питоний unicode != utf-8 (а у тебя ведь utf-8, да?), поэтому надо делать args.path.decode('utf-8'), чтобы получить тот самый unicode.

http://docs.python.org/2/howto/unicode.html#the-unicode-type

risenshnobel ★★★
()
Последнее исправление: risenshnobel (всего исправлений: 1)
Ответ на: комментарий от risenshnobel

О, стало немного яснее, спасибо.

Axon ★★★★★
() автор топика

Очень странно. Попробовал твой скрипт запустить. И он у меня ошибок не выдаёт. (Fedora19, python 2.7.5).
Можешь написать на каких именах файлов у тебя ругань происходила?

$ cat ./u.py
#!/usr/bin/python2
import os
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('path')
args = parser.parse_args()
for (dir, subsdirs, files) in os.walk(args.path):
    for file in files:
        filename = os.path.join(dir, file)
        print filename
print '-'*40
for x in os.walk(args.path):
	print x
$ ./u.py ололо
ололо/One Piece/Ророноа Зоро/Roronoa Zoro
ололо/One Piece/Ророноа Зоро/ロロノア・ ゾロ
----------------------------------------
('\xd0\xbe\xd0\xbb\xd0\xbe\xd0\xbb\xd0\xbe', ['One Piece'], [])
('\xd0\xbe\xd0\xbb\xd0\xbe\xd0\xbb\xd0\xbe/One Piece', ['\xd0\xa0\xd0\xbe\xd1\x80\xd0\xbe\xd0\xbd\xd0\xbe\xd0\xb0 \xd0\x97\xd0\xbe\xd1\x80\xd0\xbe'], [])
('\xd0\xbe\xd0\xbb\xd0\xbe\xd0\xbb\xd0\xbe/One Piece/\xd0\xa0\xd0\xbe\xd1\x80\xd0\xbe\xd0\xbd\xd0\xbe\xd0\xb0 \xd0\x97\xd0\xbe\xd1\x80\xd0\xbe', [], ['Roronoa Zoro', '\xe3\x83\xad\xe3\x83\xad\xe3\x83\x8e\xe3\x82\xa2\xe3\x83\xbb \xe3\x82\xbe\xe3\x83\xad'])

justAmoment ★★★★★
()
Ответ на: комментарий от justAmoment

Можешь написать на каких именах файлов у тебя ругань происходила?

Например, каталог «Björk».

Axon ★★★★★
() автор топика
Ответ на: комментарий от Axon

Например, каталог «Björk».

Тоже всё нормально показало.

$ mkdir Björk
$ touch один.mp3
$ touch два.mp3

$ ./u.py Björk
Björk/два.mp3
Björk/один.mp3
----------------------------------------
('Bj\xc3\xb6rk', [], ['\xd0\xb4\xd0\xb2\xd0\xb0.mp3', '\xd0\xbe\xd0\xb4\xd0\xb8\xd0\xbd.mp3'])

justAmoment ★★★★★
()
Ответ на: комментарий от risenshnobel

Точно, я не заметил. Вот и ответ.

Axon ★★★★★
() автор топика
Ответ на: комментарий от risenshnobel

А у автора треда parser.add_argument('path', type=unicode). И вся конструкция падает в момент конвертации пути в unicode.

О, действительно, если сделать с type=unicode, то ошибку выдаёт.

$ ./u.py Björk
usage: u.py [-h] path
u.py: error: argument path: invalid unicode value: 'Bj\xc3\xb6rk'
Я даже уже успел забыть когда скрипт себе копировал, что чем то мне этот параметр не понравился и я его удалил. И скрипт сразу тестировал уже без него.

justAmoment ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.