Python,UnicodeDecodeError

Python,UnicodeDecodeError,python,unicode,Python,Unicode,我得到这个错误: UnicodeDecodeError: 'ascii' codec can't decode byte 0xe0 in position 4: ordinal not in range(128) 我尝试过设置许多不同的编解码器(在标题中,如#-*-编码:utf8-*-),甚至使用u“string”,但它仍然出现 我该如何解决这个问题 编辑:我不知道造成这种情况的实际字符,但由于这是一个递归浏览文件夹的程序,它一定找到了一个名称中包含奇怪字符的文件 代码: 错误: Traceb

我得到这个错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe0 in position 4: ordinal not in range(128)
我尝试过设置许多不同的编解码器(在标题中,如
#-*-编码:utf8-*-
),甚至使用u“string”,但它仍然出现

我该如何解决这个问题

编辑:我不知道造成这种情况的实际字符,但由于这是一个递归浏览文件夹的程序,它一定找到了一个名称中包含奇怪字符的文件

代码:

错误:

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)

您是否在Windows cmd.exe框中运行此程序?如果是这样,试着在空闲状态下运行它,看看是否会出现同样的错误。Cmd.exe框不支持unicode,只支持ascii

您正试图对包含非ASCII字符的unicode字符串执行某些操作(例如打印),默认情况下该字符串将转换为ASCII。您需要指定正确表示字符串的编码。
如果您发布一些您正在尝试做的事情的示例代码,这将非常有帮助

最简单的方法是:
s=u'ma\xf1ana'
print s.encode('latin-1')

在问题中添加详细信息后编辑:

在您的情况下,您需要解码您首先读取的字符串:
f.decode()
因此,尝试改变
u“%s/%s”%(文件夹,f)


os.path.join(文件夹,f.decode())

请注意,可能需要将“latin-1”编码更改为文件的名称

注:John Machin提到了改进和清理代码的非常有用的方法+1

某些unicode项目:

  • #编码:utf-8
    放在文件顶部有时会有帮助(如果编辑器使用utf-8保存文件…)
  • s=“我是字符串”
  • u=u“我是unicode,至少在python中是这样”
  • 如果您处理文件,请尝试查看模块
进一步阅读:


我们无法猜测您要做什么,也无法猜测代码中有什么内容,无法猜测“设置多个不同的编解码器”的含义,也无法猜测u“字符串”应该为您做什么

请将代码更改为初始状态,以便尽可能地反映您正在尝试执行的操作,再次运行代码,然后编辑您的问题,以提供(1)完整的回溯和错误消息(2)包含回溯中出现的脚本中最后一条语句的片段(3)简要描述您希望代码执行的操作(4)您正在运行的Python版本

在问题中添加详细信息后编辑:

(0)让我们尝试对失败语句进行一些转换:

原件:
print“读取文件%s”%u“%s/%s%”时出错(文件夹,f)

添加空格以减少不清晰:
print“读取文件%s”%u“%s/%s%”时出错(文件夹,f)

添加括号以强调评估顺序:
打印(“读取文件%s”%u“%s/%s”)%时出错(文件夹,f)

计算括号中的(常量)表达式:
print u“读取文件%s/%s%”时出错(文件夹,f)

这真的是你想要的吗?建议:使用更好的方法构建路径一次(见下文第(2)点)

(1) 通常,使用
repr(foo)
%r”%foo
进行诊断。这样,您的诊断代码就不太可能导致异常(正如这里发生的情况),并且可以避免歧义。在尝试获取大小、重新运行和报告之前,请插入语句“打印repr(文件夹)”、“repr(f)”

(2) 不要通过
u“%s/%s%”(文件夹,文件名)
创建路径。。。使用
os.path.join(文件夹、文件名)

(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
for i in xrange(len(folders), -1, -1):
    if '$' in folders[i]:
        del folders[i]
print "Some meaningful text" # "error reading file" isn't
print "folder:", repr(folder)
print "f:", repr(f)
一种更复杂的方法是记录日志而不是打印,但上述方法比不知道发生了什么要好得多

在rtm(“os.walk”)之后进一步编辑,记住旧的图例,并重新阅读代码:

(4) 走()走过整棵树;你不需要递归地调用它

(5) 如果将unicode字符串传递给os.walk(),则结果(路径、文件名)将报告为unicode。你不需要你说的那些废话。然后,您只需选择如何显示unicode结果

(6) 删除带有“$”的路径:您必须原位修改列表,但您的方法很危险。试着这样做:

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
for i in xrange(len(folders), -1, -1):
    if '$' in folders[i]:
        del folders[i]
print "Some meaningful text" # "error reading file" isn't
print "folder:", repr(folder)
print "f:", repr(f)
(7) 您可以通过连接文件夹名和文件名来引用文件。您使用的是原始文件夹名称;当您删除递归时,这将不起作用;您需要使用os.walk报告的当前丢弃的
内容[0]

(8) 您应该发现自己在使用一些非常简单的东西,如:

for folder, subfolders, filenames in os.walk(unicoded_top_folder):
不需要
generator=os.walk(…);尝试:content=generator.next()
等,顺便说一句,如果您将来需要执行
generator.next()
,请使用
except停止迭代
而不是简单的except

(9) 如果调用者提供了一个不存在的文件夹,则不会引发异常,它只是不做任何事情。如果提供的文件夹存在但为空,同上。如果您需要区分这两个场景,您需要自己进行额外的测试

对OP评论的回应:“谢谢,请阅读信息报告()在第一篇文章中显示。我不知道为什么它打印了这么多不同的项目,但看起来它们都有问题。它们之间的共同点是它们都是.ink文件。这可能是问题所在吗?另外,在最后一篇文章中,firefox文件,它打印(Modalitrovvisoria),而Explorer中的真实文件名包含(provvisoria方式)”

(10) 嗯,那不是“.INK”.lower(),而是“.LNK”.lower()…也许你需要改变你阅读的字体

(11) 事实上,“问题”文件名都以“.l”结尾
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
>>> 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', [], [])]
>>> pp(list(os.walk(r"c:\junk\terabytest")))
[('c:\\junk\\terabytest',
  ['empty'],
  ['Ha\x9aek.txt', 'tbyte1.py', '\xd0.txt']),
 ('c:\\junk\\terabytest\\empty', [], [])]
>>> u'\u0161'.encode('cp1252')
'\x9a'
>>> 'Ha\x9aek'.decode('cp1252')
u'Ha\u0161ek'
>>> '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
>>> 'Ha\x9aek'.decode('latin1')
u'Ha\x9aek'
>>> unicodedata.name(u'\u0161')
'LATIN SMALL LETTER S WITH CARON'
>>>
IDLE 2.6.4      
>>> import os
>>> from pprint import pprint as pp
>>> pp(list(os.walk(ur"c:\junk\terabytest\chinese")))
[(u'c:\\junk\\terabytest\\chinese', [], [u'nihao\u4f60\u597d.txt'])]
>>> print list(os.walk(ur"c:\junk\terabytest\chinese"))[0][2][0]
nihao你好.txt
>>> pp(list(os.walk(r"c:\junk\terabytest\chinese")))
[('c:\\junk\\terabytest\\chinese', [], ['nihao??.txt'])]
u"%s" % f
uf = f.decode('utf-8')
print uf.encode('utf-8')
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'))
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))