Это выводит "UnicodeDecodeError: кодек 'ASCII' не может декодировать байт 0xc2 в положении 2: порядковый не в диапазоне (128)" при выполнении после кода:
filename = 'Spywaj.ttf'
print repr(filename)
>> 'Sp\xc2\x88ywaj.ttf'
filepath = os.path.join('/dirname', filename)
Но файл является правильным и существовал на диске. Имя файла было извлечено из, "разархивировали-l" команда. Как именам файлов соединения может понравиться это?
ОС и файловая система
Filesystem: ext3 relatime,errors=remount-ro 0 0
Locale: en_US.UTF-8
Предложение Alex os.path.join работает теперь, но я все еще не могу получить доступ к файлу на диске с именем файла, к которому это присоединилось.
filename = filename.decode('utf-8')
filepath = os.path.join('/dirname', filename)
print filepath
>> /dirname/u'Sp\xc2\x88ywaj.ttf'
print os.path.isfile(filepath)
>> False
new_filepath = filepath.encode('Latin-1').encode('utf-8')
print new_filepath
>> /dirname/u'Sp\xc2\x88ywaj.ttf'
print type(filepath)
>> <type 'unicode'>
print os.path.isfile(new_filepath)
>> False
valid_filepath = glob.glob('/dirname/*.ttf')[0]
print valid_filepath
>> /dirname/Spywaj.ttf (SO cannot display the chars in filename)
print type(valid_filepath)
>> <type 'str'>
print os.path.isfile(valid_filepath)
>> True
Как в латинице-1 (ISO-8859-1), так и в Windows-1252, 0xc2 означало бы заглавную букву A с круговым акцентом... кажется, нигде в коде, который вы показываете! Не могли бы вы добавить a
print repr(filename)
перед вызовом os.path.join
(а также поместить '/dirname'
в переменную и распечатать ее переиздание для полноты?). Я думаю, что, возможно, этот шальной символ есть , но по какой-то причине вы его не видите -- repr
откроет его.
Если у вас в имени файла есть латинский-1 (или Win-1252) не-Ascii символ, вы должны использовать Юникод -- и/или, в зависимости от вашей операционной системы и файловой системы, некоторую специфическую кодировку этого символа.
Edit: операционная система подтверждает, благодаря repr
, что на самом деле существует два байта, которые не могут быть ASCII -- 0xc2, а затем 0x88, что соответствует тому, что операционная система думает, что это один нижний регистр L.
Ну, эта последовательность была бы Unicode заглавной A с кареттой (кодовая точка 0x88) в справедливо популярной кодировке UTF-8 - как это может выглядеть как строчная L для объяснения нищих OP, но я представляю некоторые шрифты могут быть достаточно безумными с графической точки зрения, чтобы позволить себе такую путаницу.
Поэтому я сначала попробую filename = filename.decode('utf-8')
-- это должно позволить os.path.join
работать. Если open
then balks at the result Unicode string (это может сработать, в зависимости от файловой системы и операционной системы), то следующая попытка - попробовать использовать объект Юникод .encode('Latin-1')
и .encode('utf-8')
. Если ни одна из кодировок не работает, то информация об используемой операционной системе и файловой системе, которую операционная система, я полагаю, еще не дала, становится критичной.
Выбрасывает "UnicodeDecodeError: Кодек 'ascii' не может декодировать байт 0xc2 в позиции 2: ordinal not in range(128)" при выполнении следующего кода:
filename = 'Spywaj.ttf'
print repr(filename)
>> 'Sp\xc2\x88ywaj.ttf'
filepath = os.path.join('/dirname', filename)
Я не понимаю, как можно получить это исключение -- оба аргумента os. path.join являются объектами str. Нет причин пытаться преобразовать что-либо в юникод. Вы уверены, что приведенный выше код - это именно то, что вы запустили?
Предложение Алекса os.path.join сейчас работает, но я все еще не могу получить доступ к файлу на диске с именем файла, к которому он присоединился.
filename = filename.decode('utf-8')
filepath = os.path.join('/dirname', filename)
print filepath
>> /dirname/u'Sp\xc2\x88ywaj.ttf'
Извините, если предположить, что имя файла
не изменилось по сравнению с предыдущим фрагментом, то это определенно невозможно. Похоже на результат os.path.join('/dirname', repr(filename))
... пожалуйста, убедитесь, что вы опубликовали код, который вы на самом деле запустили, вместе с реальным выводом (и реальной трассировкой, если таковая имеется).
new_filepath = filepath.encode('Latin-1').encode('utf-8')
Alex имел в виду попробовать дважды, каждый раз с одной из этих кодировок - а не один раз с обеими кодировками! Так как все символы в filepath были в диапазоне ASCII (см. проблему с доказательствами 2), эффект был просто filepath.encode('ascii')
Вы знаете, как найти имя файла, который вас интересует:
valid_filepath = glob.glob('/dirname/*.ttf')[0]
Если вам нужно жестко закодировать это имя в вашем скрипте, вы можете использовать функцию repr(), чтобы получить представление, которое вы можете ввести в ваш скрипт, не беспокоясь о utf8, unicode, кодировке, декодировании и всех этих шумах:
print repr(valid_filepath)
Предположим, что он печатает '/dirname/Sp\xc2\x88ywaj.ttf'
... тогда все, что вам нужно сделать, это аккуратно скопировать это и вставить его в свой сценарий:
file_path = '/dirname/Sp\xc2\x88ywaj.ttf'
filename = filename.decode('utf-8').encode("latin-1")
]
[] работает на меня с файлом из [] Splywaj.zip[][
]. [>>> os.path.isfile(filename.decode("utf8").encode("latin-1"))
True
>>>
]