Python, UnicodeDecodeError

Я получаю эту ошибку:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe0 in position 4: ordinal not in range(128) 

Я попытался установить множество разных кодеков (в заголовке, например, # -*- coding: utf8 -*- ), или даже с помощью u "string", но он по-прежнему появляется.

Как это исправить?

Изменить: я не знаю фактического персонажа, который вызывает это, но поскольку это программа, которая рекурсивно просматривает папки, она должна найти файл со странными символами в его имени

Код:

 # -*- coding: utf8 -*- # by TerabyteST ########################### # Explores given path recursively # and finds file which size is bigger than the set treshold import sys import os class Explore(): def __init__(self): self._filelist = [] def exploreRec(self, folder, treshold): print folder generator = os.walk(folder + "/") try: content = generator.next() except: return folders = content[1] files = content[2] for n in folders: if "$" in n: folders.remove(n) for f in folders: self.exploreRec(u"%s/%s"%(folder, f), treshold) for f in files: try: rawsize = os.path.getsize(u"%s/%s"%(folder, f)) except: print "Error reading file %s"%u"%s/%s"%(folder, f) continue mbsize = rawsize / (1024 * 1024.0) if mbsize >= treshold: print "File %s is %d MBs!"%(u"%s/%s"%(folder, f), mbsize) 

Ошибка:

 Traceback (most recent call last): File "<pyshell#19>", line 1, in <module> a.exploreRec("C:", 100) File "D:/Python/Explorator/shitfinder.py", line 35, in exploreRec print "Error reading file %s"%u"%s/%s"%(folder, f) UnicodeDecodeError: 'ascii' codec can't decode byte 0xe0 in position 4: ordinal not in range(128) 

Вот что показано с помощью print repr("Error reading file %s"%u"%s/%s"%(folder.decode('utf-8','ignore'), f.decode('utf-8','ignore')))

 >>> a = Explore() >>> a.exploreRec("C:", 100) File C:/Program Files/Ableton/Live 8.0.4/Resources/DefaultPackages/Live8Library_v8.2.alp is 258 MBs! File C:/Program Files/Adobe/Reader 9.0/Setup Files/{AC76BA86-7AD7-1040-7B44-A90000000001}/Data1.cab is 114 MBs! File C:/Program Files/Microsoft Games/Age of Empires III/art/Art1.bar is 393 MBs! File C:/Program Files/Microsoft Games/Age of Empires III/art/art2.bar is 396 MBs! File C:/Program Files/Microsoft Games/Age of Empires III/art/art3.bar is 228 MBs! File C:/Program Files/Microsoft Games/Age of Empires III/Sound/Sound.bar is 273 MBs! File C:/ProgramData/Microsoft/Search/Data/Applications/Windows/Windows.edb is 162 MBs! REPR: u"Error reading file C:/ProgramData/Microsoft/Windows/GameExplorer/{1B4801C1-CA86-487E-8347-B26F1CCB2F75}/SupportTasks/0/Sito web di Mirror's Edge.lnk" END REPR: Error reading file C:/ProgramData/Microsoft/Windows/GameExplorer/{1B4801C1-CA86-487E-8347-B26F1CCB2F75}/SupportTasks/0/Sito web di Mirror's Edge.lnk REPR: u"Error reading file C:/ProgramData/Microsoft/Windows/GameExplorer/{1B4801C1-CA86-487E-8347-B26F1CCB2F75}/SupportTasks/1/Contenuti scaricabili di Mirror's Edge.lnk" END REPR: Error reading file C:/ProgramData/Microsoft/Windows/GameExplorer/{1B4801C1-CA86-487E-8347-B26F1CCB2F75}/SupportTasks/1/Contenuti scaricabili di Mirror's Edge.lnk REPR: u'Error reading file C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Google Talk/Supporto/Modalitiagnostica di Google Talk.lnk' END REPR: Error reading file C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Google Talk/Supporto/Modalitiagnostica di Google Talk.lnk REPR: u'Error reading file C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Microsoft SQL Server 2008/Strumenti di configurazione/Segnalazione errori e utilizzo funzionaliti SQL Server.lnk' END REPR: Error reading file C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Microsoft SQL Server 2008/Strumenti di configurazione/Segnalazione errori e utilizzo funzionaliti SQL Server.lnk REPR: u'Error reading file C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Mozilla Firefox/Mozilla Firefox ( Modalitrovvisoria).lnk' END REPR: Error reading file C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Mozilla Firefox/Mozilla Firefox ( Modalitrovvisoria).lnk REPR: u'Error reading file C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Mozilla Firefox 3.6 Beta 1/Mozilla Firefox 3.6 Beta 1 ( Modalitrovvisoria).lnk' END REPR: Error reading file C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Mozilla Firefox 3.6 Beta 1/Mozilla Firefox 3.6 Beta 1 ( Modalitrovvisoria).lnk Traceback (most recent call last): File "<pyshell#21>", line 1, in <module> a.exploreRec("C:", 100) File "D:/Python/Explorator/shitfinder.py", line 30, in exploreRec self.exploreRec(("%s/%s"%(folder, f)).encode("utf-8"), treshold) File "D:/Python/Explorator/shitfinder.py", line 30, in exploreRec self.exploreRec(("%s/%s"%(folder, f)).encode("utf-8"), treshold) File "D:/Python/Explorator/shitfinder.py", line 30, in exploreRec self.exploreRec(("%s/%s"%(folder, f)).encode("utf-8"), treshold) File "D:/Python/Explorator/shitfinder.py", line 30, in exploreRec self.exploreRec(("%s/%s"%(folder, f)).encode("utf-8"), treshold) File "D:/Python/Explorator/shitfinder.py", line 30, in exploreRec self.exploreRec(("%s/%s"%(folder, f)).encode("utf-8"), treshold) File "D:/Python/Explorator/shitfinder.py", line 30, in exploreRec self.exploreRec(("%s/%s"%(folder, f)).encode("utf-8"), treshold) UnicodeDecodeError: 'ascii' codec can't decode byte 0x99 in position 78: ordinal not in range(128) >>> 

8 Solutions collect form web for “Python, UnicodeDecodeError”

Мы не можем догадываться о том, что вы пытаетесь сделать, и о том, что в вашем коде, а не о том, что означает «установка многих разных кодеков», а не о том, что для вас должно использовать «строка».

Пожалуйста, измените свой код на его исходное состояние, чтобы он отражал как можно лучше то, что вы пытаетесь сделать, запустите его снова, а затем отредактируйте свой вопрос, чтобы предоставить (1) полное сообщение о трассировке и ошибке, которое вы получили (2) фрагмент охватывая последнее заявление в вашем скрипте, которое появляется в traceback (3), краткое описание того, что вы хотите сделать для кода (4), какую версию Python вы используете.

Изменить после добавления деталей к вопросу:

(0) Давайте попробуем некоторые преобразования в ошибке:

Оригинал:
print "Error reading file %s"%u"%s/%s"%(folder, f)
Добавить пробелы для уменьшения неразборчивости:
print "Error reading file %s" % u"%s/%s" % (folder, f)
Добавьте круглые скобки, чтобы подчеркнуть порядок оценки:
print ("Error reading file %s" % u"%s/%s") % (folder, f)
Вычислить (константу) выражение в круглых скобках:
print u"Error reading file %s/%s" % (folder, f)

Это действительно то, что вы намеревались? Предложение: постройте путь ONCE, используя лучший метод (см. Пункт (2) ниже).

(1) В общем случае используйте repr(foo) или "%r" % foo для диагностики. Таким образом, ваш диагностический код гораздо реже вызывает исключение (как это происходит здесь) И вы избегаете двусмысленности. Вставьте инструкцию print repr(folder), repr(f) прежде чем пытаться получить размер, повторить и отправить отчет.

(2) Не os.path.join(folder, filename) пути через u"%s/%s" % (folder, filename) … используйте os.path.join(folder, filename)

(3) У вас нет голых исключений, проверьте известные проблемы. Чтобы неизвестные проблемы не остались неизвестными, сделайте следующее:

 try: some_code() except ReasonForBaleOutError: continue except: # something's gone wrong, so get diagnostic info print repr(interesting_datum_1), repr(interesting_datum_2) # ... and get traceback and error message raise 

Более сложный способ связан с журналированием вместо печати, но выше это намного лучше, чем не знать, что происходит.

Дальнейшие изменения после rtm («os.walk»), запоминание старых легенд и повторное чтение вашего кода:

(4) os.walk () проходит по всему дереву; вам не нужно вызывать его рекурсивно.

(5) Если вы передаете строку unicode в os.walk (), результаты (пути, имена файлов) сообщаются как unicode. Тебе не нужны все, что у "бла". Тогда вам просто нужно выбрать, как вы показываете результаты Unicode.

(6) Удаление путей с помощью «$» в них: вы должны изменить список на месте, но ваш метод опасен. Попробуйте что-то вроде этого:

 for i in xrange(len(folders), -1, -1): if '$' in folders[i]: del folders[i] 

(7) Обращайтесь к файлам, введя имя папки и имя файла. Вы используете имя папки ORIGINAL; когда вы вырвите рекурсию, это не сработает; вам нужно будет использовать текущее content[0] , указанное os.walk.

(8) Вы должны найти себе что-то очень простое:

 for folder, subfolders, filenames in os.walk(unicoded_top_folder): 

Нет необходимости в generator = os.walk(...); try: content = generator.next() generator = os.walk(...); try: content = generator.next() т. д. и BTW, если вам когда-либо понадобится generator.next() в будущем, используйте вместо except StopIteration вместо голого, кроме.

(9) Если вызывающий абонент предоставляет несуществующую папку, исключение не возникает, оно просто ничего не делает. Если предоставленная папка существует, но пуста, то же самое. Если вам нужно провести различие между этими двумя сценариями, вам нужно будет провести дополнительное тестирование самостоятельно.

Ответ на этот комментарий от OP: «« Спасибо, пожалуйста, прочитайте info repr (), показанный в первом сообщении. Я не знаю, почему в нем напечатано столько разных элементов, но похоже, что у всех у них проблемы. что все они – это файлы .ink. Может быть, проблема? Также, в последних, firefox, он печатает (Modalitrovvisoria), в то время как настоящее имя файла из Explorer содержит (Modalità provvisoria) "" "

(10) Умм это не «.INK» .lower (), это «.LNK» .lower () … возможно, вам нужно изменить шрифт во всем, что вы читаете.

(11) Тот факт, что имена «проблемных» имен заканчиваются на «.lnk» / может / быть чем-то связанным с os.walk () и / или Windows, делает что-то особенное с именами этих файлов.

(12) Я повторяю здесь утверждение Python, которое вы использовали для создания этого вывода, с введенным пробелом:

 print repr( "Error reading file %s" \ % u"%s/%s" % ( folder.decode('utf-8','ignore'), f.decode('utf-8','ignore') ) ) 

Кажется, что вы не прочитали или не поняли или просто проигнорировали совет, который я дал вам в комментарии к другому ответу (и ответам ответчика): UTF-8 НЕ относится к контексту имен файлов в файле Windows система.

Нас интересует именно то, что относятся к папке и f. Вы попирали все доказательства, пытаясь расшифровать его с помощью UTF-8. Вы усугубили обфускацию, используя опцию «игнорировать». Если бы вы использовали опцию «replace», вы бы увидели «(Modalit \ ufffdrovvisoria)». Опция «игнорировать» не имеет места в отладке.

В любом случае, факт, что некоторые из названий файлов имели какую-то ошибку, но появившийся НЕ потерять символы с опцией «игнорировать» (или, казалось, НЕ был искалечен), является подозрительным.

Какая часть "" "Вставить инструкцию print repr(folder), repr(f) " "" вы не поняли? Все, что вам нужно сделать, это что-то вроде этого:

 print "Some meaningful text" # "error reading file" isn't print "folder:", repr(folder) print "f:", repr(f) 

(13) Также представляется, что вы внесли UTF-8 в другое место в своем коде, судя по self.exploreRec(("%s/%s"%(folder, f)).encode("utf-8"), treshold) : self.exploreRec(("%s/%s"%(folder, f)).encode("utf-8"), treshold)

Я хотел бы указать, что вы все еще не знаете, относятся ли папки и f к объектам str или объектам unicode, а два ответа предположили, что они, скорее всего, являются объектами str, поэтому зачем вводить blahbah.encode () ??

Более общий момент: попытайтесь понять, каковы ваши проблемы или проблемы, ПЕРЕД заменой скрипта. Трэшинг о попытке каждого предложения в сочетании с эффективной технологией отладки с нулевым нулевым временем – это не путь вперед.

(14) Когда вы снова запускаете свой скрипт, вам может понадобиться уменьшить объем вывода, запустив его над некоторым подмножеством C: \ … особенно если вы приступите к моему первоначальному предложению, чтобы иметь отладочную печать всех имен файлов, не только ошибочные (зная, как выглядят не ошибки), они могут помочь в понимании проблемы).

Ответ на функцию «очистки» Брайана МакЛемора:

(15) Вот аннотированный интерактивный сеанс, который иллюстрирует, что на самом деле происходит с именами файлов os.walk () и non-ASCII:

 C:\junk\terabytest>dir [snip] Directory of C:\junk\terabytest 20/11/2009 01:28 PM <DIR> . 20/11/2009 01:28 PM <DIR> .. 20/11/2009 11:48 AM <DIR> empty 20/11/2009 01:26 PM 11 Hašek.txt 20/11/2009 01:31 PM 1,419 tbyte1.py 29/12/2007 09:33 AM 9 Ð.txt 3 File(s) 1,439 bytes [snip] C:\junk\terabytest>\python26\python Python 2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit (Intel)] onwin32 Type "help", "copyright", "credits" or "license" for more information. >>> from pprint import pprint as pp >>> import os 

os.walk (unicode_string) -> приводит к юникодным объектам

 >>> pp(list(os.walk(ur"c:\junk\terabytest"))) [(u'c:\\junk\\terabytest', [u'empty'], [u'Ha\u0161ek.txt', u'tbyte1.py', u'\xd0.txt']), (u'c:\\junk\\terabytest\\empty', [], [])] 

os.walk (str_string) -> приводит к объектам str

 >>> pp(list(os.walk(r"c:\junk\terabytest"))) [('c:\\junk\\terabytest', ['empty'], ['Ha\x9aek.txt', 'tbyte1.py', '\xd0.txt']), ('c:\\junk\\terabytest\\empty', [], [])] 

cp1252 – это кодировка, которую я ожидаю использовать в своей системе …

 >>> u'\u0161'.encode('cp1252') '\x9a' >>> 'Ha\x9aek'.decode('cp1252') u'Ha\u0161ek' 

декодирование str с помощью UTF-8 не работает, как и ожидалось

 >>> 'Ha\x9aek'.decode('utf8') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\python26\lib\encodings\utf_8.py", line 16, in decode return codecs.utf_8_decode(input, errors, True) UnicodeDecodeError: 'utf8' codec can't decode byte 0x9a in position 2: unexpected code byte 

Любая случайная строка байтов может быть декодирована без ошибок, используя latin1

 >>> 'Ha\x9aek'.decode('latin1') u'Ha\x9aek' 

НО U + 009A является управляющим символом (ОДИНОЧНЫЙ ХАРАКТЕР ВВЕДЕНИЕ), т. Е. Бессмысленная тарабарщина; абсолютно никакого отношения к правильному ответу

 >>> unicodedata.name(u'\u0161') 'LATIN SMALL LETTER S WITH CARON' >>> 

(16) Этот пример показывает, что происходит, когда символ представлен в наборе символов по умолчанию; что произойдет, если это не так? Вот пример (с использованием IDLE на этот раз) имени файла, содержащего идеограммы CJK, которые определенно не представлены в моем наборе символов по умолчанию:

 IDLE 2.6.4 >>> import os >>> from pprint import pprint as pp 

repr (результаты Unicode) выглядит отлично

 >>> pp(list(os.walk(ur"c:\junk\terabytest\chinese"))) [(u'c:\\junk\\terabytest\\chinese', [], [u'nihao\u4f60\u597d.txt'])] 

и unicode отображает только штраф в IDLE:

 >>> print list(os.walk(ur"c:\junk\terabytest\chinese"))[0][2][0] nihao你好.txt 

Результат str, очевидно, создается с использованием .encode (что бы то ни было, «replace») – не очень полезно, например, вы не можете открыть файл, передав его как имя файла.

 >>> pp(list(os.walk(r"c:\junk\terabytest\chinese"))) [('c:\\junk\\terabytest\\chinese', [], ['nihao??.txt'])] 

Таким образом, вывод заключается в том, что для достижения наилучших результатов следует передавать строку unicode в os.walk () и решать любые проблемы с отображением.

По умолчанию Python использует кодировку ASCII, что раздражает. Если вы хотите изменить его навсегда, найдите и отредактируйте файл site.py , найдите def setencoding() и несколько строк ниже, измените encoding = "ascii" на encoding = "utf-8" . Пока, по умолчанию ASCII кодирование.

Вы пытаетесь выполнить какое-либо действие (например, печать) в строке юникода, содержащей не-ASCII-символы, и строка по умолчанию преобразуется в ascii. Вам нужно будет указать кодировку, чтобы правильно представлять строку.
Это поможет значительно, если вы разместите некоторый пример кода того, что вы пытаетесь сделать.

Самый простой способ сделать это:
s = u'ma\xf1ana';
print s.encode('latin-1');

Отредактировано после добавления деталей к вопросу:

В вашем случае вам необходимо декодировать строку, которую вы читаете вначале:
f.decode(); ,
поэтому попробуйте изменить
u"%s/%s" % (folder, f)
в
os.path.join(folder, f.decode())

Обратите внимание, что для кодирования «latin-1» может потребоваться изменение имени файла с именем

PS: Джон Мачин упомянул очень полезные способы улучшения и очистки кода. +1

Вы запускаете эту программу в окне cmd.exe Windows? Если это так, попробуйте запустить его в IDLE и посмотреть, есть ли у вас одинаковые ошибки. В поле Cmd.exe не выполняется unicode, а только ascii.

Некоторые элементы юникода:

  • размещение # encoding: utf-8 в верхней части файла иногда помогает (если ваш редактор использует UTF-8 для сохранения вашего файла …)
  • s = "i'm a string"
  • u = u"i'm unicode, at least in python < ۳"
  • Если ваша работа с файлами пытается заглянуть в модуль кодеков .

Дальнейшие чтения:

 u"%s" % f 

В разных местах вы делаете что-то похожее на вышеупомянутый код. Это неверный способ преобразования объекта str в объект unicode, поскольку преобразование выполняется с помощью sys.getdefaultencoding () (ascii), что почти гарантировано.

Вы должны использовать методы кодирования / декодирования для преобразования в / из объекта unicode. Это требует знания того, что кодирует ваш вход (строки, возвращенные из os.walk). Например, если имена файлов закодированы в UTF-8

 uf = f.decode('utf-8') 

интерпретирует f как кодированную последовательность байтов UTF-8 и возвращает соответствующий объект unicode. Аналогично, когда вам нужно вывести объект unicode, вы должны преобразовать его обратно в str, указав действительную кодировку, которую вы хотите вывести.

 print uf.encode('utf-8') 

У меня было несчастье работать в некоторых кодах, которые не соответствовали их кодировке.

Это функция, которую мы использовали, чтобы помочь очистить ее:

 def to_unicode(value): if isinstance(value, unicode): return value elif isinstance(value, str): try: if value.startswith('\xff\xfe'): return value.decode('utf-16-le') elif value.startswith('\xfe\xff'): return value.decode('utf-16-be') else: return value.decode('utf-8') except UnicodeDecodeError: return value.decode('latin-1') else: try: return unicode(value) except UnicodeError: return to_unicode(str(value)) except TypeError: if hasattr(value, '__unicode__'): return value.__unicode__() 

Таким образом, используя эту функцию, вы можете использовать:

 print u"Error reading file %s/%s" % (to_unicode(folder), to_unicode(f)) 

вместо того, чтобы делать:

 print "Error reading file %s"%u"%s/%s"%(folder, f) 

Попробуй это:

 print "Error reading file %s"%u"%s/%s"%(folder.encode('ascii','ignore'), f.encode('ascii','ignore')) 

Поскольку консоль не может печатать символы юникода, вы можете увидеть правильное имя. «ignore» сообщает кодеку пропустить эти символы. вы также можете использовать 'replace' (печатает '?'), 'xmlcharrefreplace' (заменяет на & x #### кодовой точки), 'backslashreplace' (заменяет код \ x ###### кода)

Вам нужно будет закодировать каждую строку в Юникоде, как вы это напечатаете.

  • Проблемы с кодировкой Python и BeautifulSoup
  • Невозможно декодировать строку Unicode в Python 2.4
  • python: unicode в терминале Windows, используется кодировка?
  • python - Проблема сохранения символа Unicode для MySQL с Django
  • Python 2.7 UnicodeDecodeError: кодек 'ascii' не может декодировать байт
  • python: открыть и прочитать файл, содержащий germanic umlaut, как unicode
  • Django создает CSV-файл, который содержит Unicode и может быть открыт непосредственно с помощью Excel
  • Что такое строка в Юникоде?
  • Как заставить str.translate работать с строками Unicode?
  • Самый быстрый способ преобразования ключей и значений dict из str в Unicode?
  • Тип и формат sys.exc_info () в Python 2.71
  •  
    Interesting Posts for Van-Lav

    UnicodeDecodeError: кодек ascii не может декодировать байт 0xe2 в позиции 13: порядковый номер не в диапазоне (128)

    SOAP suds и ужасная схема Тип Не найдена ошибка

    Отправка строк между скриптами Python с использованием подпроцессов PIPE

    как заставить SQLlite выбрать для поведения транзакции обновления в sqlalchemy

    Почему Django продолжает запрашивать типы контента, являются устаревшими и их необходимо удалить

    выберите на основе временной метки и отметки времени обновления с нулевым значением

    Возврат строки из CSV, если указанное значение в строке соответствует условию

    постоянно контролировать программу / процесс с помощью python

    Как я могу захватить цвет пикселя на рабочем столе? (Linux)

    Webapp2 для аутентификации и входа в систему

    Как преобразовать массив Numpy в изображение PIL с использованием matplotlib colormap

    Получение списка определенных элементов индекса из списка словарей в python (понимание списка)

    Просить пользователя вводить только ограниченное количество времени в python

    Есть ли ограничение на количество таблиц, которые может иметь база данных PostgreSQL?

    Как реализовать интенсивный скрипт python для тестирования

    Python - лучший язык программирования в мире.