我试图从ISO-8859-1中编码的文件中读取一堆电子邮件,然后将它们(部分)写入带有UTF-8编码的JSON文件中。我目前有一个程序可以读取它们并生成包含str
类型属性的对象,其中包含消息的各个字段。我想将这些str
字符串(编码位串)转换为unicode
字符串(抽象Unicode对象),以便稍后我可以在写出文件时使用UTF-8对它们进行重新编码。所以我使用decode
的{{1}}方法,如下所示:
str
根据我读过的文档,msg_dict = {u'Id' : message.message_id.decode('iso-8859-1'),
u'Subject' : message.subject.decode('iso-8859-1'),
u'SenderEmail' : message.sender_email.decode('iso-8859-1'),
u'SenderName' : message.sender_name.decode('iso-8859-1'),
u'Date': message.date.isoformat()}
应该使用decode
对象,根据给定的编码解释其字节,并返回表示这些字符的str
对象。但是当我运行我的代码时,我收到了这个错误:
unicode
当我致电解码时,如何才能收到编码错误?我最好的猜测是Python决定使用默认编码自动将返回的 File "/home/edward/long/path/omitted/dumpMails.py", line 38, in <module>
u'Subject' : message.subject.decode('iso-8859-1'),
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 1: ordinal not in range(128)
转换回unicode
。但为什么要这样做呢?将str
放入字典中是否有用?
答案 0 :(得分:4)
Python将自动尝试编码值,如果它还不是字节字符串。毕竟,您无法解码Unicode字符串,因此Python会尝试提供帮助并尝试将其作为字节串首先。
换句话说,字符串已经解码为unicode :
>>> decoded = u'åüøî'
>>> decoded.decode('latin1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)
您必须测试它是否已经是Unicode字符串,或者总是是Unicode字符串,只是不要尝试解码它。
顺便提一下,如果你有一个你想要编码的字节字符串,你会看到反问题; Python将首先隐式解码这样的值,以便它有一个unicode
对象来为你编码:
>>> encoded = u'åüøî'.encode('utf8')
>>> encoded.encode('latin1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
请注意该错误消息中的 decode 关键字。