Python,UnicodeDecodeError - python

我收到此错误:

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)
>>> 

python大神给出的解决方案

我们无法猜测您想做什么,您的代码中没有什么,“设置许多不同的编解码器”意味着什么,您“字符串”应该为您做什么。

请将您的代码更改为其初始状态,以使其尽可能地反映您要尝试执行的操作,再次运行它,然后编辑问题以提供(1)您获得的完整追溯和错误消息(2)代码段包含脚本中出现在回溯中的最后一条语句(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)请勿使用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文件夹名称;当您退出递归时,这将不起作用;您需要使用os.walk报告的当前丢弃的content[0]值。

(8)您应该使用一些非常简单的方法:

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

如果将来将来需要使用generator = os.walk(...); try: content = generator.next(),则不需要generator.next()等和BTW,请使用except StopIteration代替裸机。

(9)如果调用方提供了一个不存在的文件夹,则不会引发异常,它什么也不做。如果提供的文件夹存在但为空,则同上。如果需要区分这两种情况,则需要自己进行额外的测试。

回复来自OP的评论:“”谢谢,请阅读第一篇文章中显示的信息repr()。我不知道为什么它打印了这么多不同的项目,但看起来它们都有问题。它们之间的共同点是它们是.ink文件。可能是问题所在吗?此外,在最后一个文件中,Firefox会打印(Modalitrovvisoria),而资源管理器中的真实文件名包含(Modalitàprovvisoria)“” ”

(10)嗯,不是“ .INK” .lower(),而是“ .LNK” .lower()...也许您需要在阅读字体时更改字体。

(11)“问题”文件名都以“ .lnk” / may /结尾的事实可能与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对其进行解码,从而践踏了所有证据。您已经使用“忽略”选项使混淆变得更加复杂。如果您使用了“替换”选项,您将看到“((Modalit \ ufffdrovvisoria)””。 “忽略”选项在调试中没有位置。

在任何情况下,某些文件名都有某种错误,但使用“ ignore”选项似乎不会丢失字符(或看上去不会被损坏),这一事实是可疑的。

您不理解“”“的哪一部分插入语句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)

我想指出的是,您仍然不知道folder和f是指str对象还是unicode对象,两个答案表明它们很可能是str对象,因此为什么要引入blahbah.encode()?

更笼统的观点:在更改脚本之前,尝试了解您的问题所在。尝试尝试每一个建议并加上接近零的有效调试技术,这并不是前进的道路。

(14)当您再次运行脚本时,您可能希望通过在C:\ ...的某个子集上运行来减少输出的数量,特别是如果您按照我最初的建议对所有文件名进行调试打印,不仅是错误的错误(知道非错误的错误看起来可能有助于理解问题)。

回应Bryan McLemore的“清理”功能:

(15)这是一个带注释的交互式会话,它说明os.walk()和非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)->产生unicode对象

>>> 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'

如预期那样,用UTF-8解码str无法正常工作

>>> '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)该示例显示了在默认字符集中可以表示该字符的情况;如果不是,会发生什么?这是一个包含CJK表意文字的文件名示例(这次使用IDLE),在我的默认字符集中肯定无法表示这些文件:

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(无论如何,“替换”)产生的-并不是很有用。您不能通过将其作为文件名来打开文件。

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

因此得出的结论是,为了获得最佳结果,应该将unicode字符串传递给os.walk(),并处理任何显示问题。

用大写字母拆分字符串,但忽略AAA Python Regex - python

我的正则表达式:vendor = "MyNameIsJoe. I'mWorkerInAAAinc." ven = re.split(r'(?<=[a-z])[A-Z]|[A-Z](?=[a-z])', vendor) 以大写字母分割字符串,例如:'我的名字是乔。 I'mWorkerInAAAinc”变成…

在Flask中测试文件上传 - python

我在Flask集成测试中使用Flask-Testing。我有一个表单,该表单具有我要为其编写测试的徽标的文件上传,但是我不断收到错误消息:TypeError: 'str' does not support the buffer interface。我正在使用Python3。我找到的最接近的答案是this,但是它对我不起作用。这是我的许多尝…

Spacy如何将标记标签整体化? - python

在包含#标签(例如tweet)的句子中,spacy的令牌生成器将标签分为两个令牌:import spacy nlp = spacy.load('en') doc = nlp(u'This is a #sentence.') [t for t in doc] 输出:[This, is, a, #, sentence, .…

在熊猫中,如何从单词列表或单词集中选择数据框中的短语? - python

在Python3和熊猫中,我具有数据框:df_projetos_api_final.info() <class 'pandas.core.frame.DataFrame'> Int64Index: 93631 entries, 1 to 93667 Data columns (total 21 columns): AnoMat…

Python:同时在for循环中添加到列表列表 - python

我想用for循环外的0索引值创建一个新列表,然后使用for循环添加到相同的列表。我的玩具示例是:import random data = ['t1', 't2', 't3'] masterlist = [['col1', 'animal1', 'an…