将Unicode转换为python

时间:2012-11-21 02:39:42

标签: python unicode utf-8

  

可能重复:
  Convert Unicode to UTF-8 Python

我是一个非常新的python程序员,正在处理我的第一个脚本。该脚本从plist字符串中提取文本,然后对其执行一些操作,然后将其打包为HTML电子邮件。

从一些条目中,我得到了可怕的Unicode"在序号128"之外错误。

尽可能多地阅读有关编码和解码的内容,但我知道对我来说编码很重要,但我很难理解何时或如何准确地执行此操作。< / p>

首先使用plistlib拉入违规变量,并从markdown转换为HTML,如下所示:

entry = result['Entry Text']
donotecontent = markdown2.markdown(entry)

稍后,它将被放入这样的电子邮件中:

html = donotecontent + '<br /><br />' + var3
part1 = MIMEText(html, 'html')
msg.attach(part1)

我的问题是,对于我来说,确保此内容中的Unicode字符不会导致此错误的最佳方法是什么。我不想忽视这些角色。

3 个答案:

答案 0 :(得分:11)

抱歉我的英语不好。我说中文/日文,每天使用CJK字符。 Ceron几乎解决了这个问题,因此我不再讨论如何再次使用encode() / decode()

当我们使用str()来转换任何unicode对象时,它会将unicode字符串编码为bytedata;当我们使用unicode()来转换str对象时,它会将bytedata解码为unicode字符。

并且,编码必须是从sys.getdefaultencoding()返回的内容。

默认情况下,sys.getdefaultencoding()默认返回'ascii',执行str() / unicode()投射时可能会抛出编码/解码异常。

如果你想做str&lt; - &gt; str()unicode()的unicode转换,以及使用'utf-8'进行编码/解码,您可以执行以下语句:

import sys    # sys.setdefaultencoding is cancelled by site.py
reload(sys)    # to re-enable sys.setdefaultencoding()
sys.setdefaultencoding('utf-8')

它将导致稍后执行str()unicode()转换任何带有编码utf-8的basetring对象。

但是,我更乐意明确使用encode() / decode(),因为它可以让我更轻松地维护代码。

答案 1 :(得分:4)

假设您使用的是Python 2.x,请记住:有两种类型的字符串:strunicodestr是字节字符串,而unicode是unicode字符串。 unicode字符串可用于表示任何语言的文本,但要将文本存储在计算机中或通过电子邮件发送,您需要使用字节表示该文本。要使用字节表示文本,您需要一种编码格式。有许多编码格式,默认情况下Python使用 ascii ,但 ascii 只能代表几个字符,主要是英文字母。如果您尝试使用 ascii 对包含其他字母的文本进行编码,您将获得着名的“外部序数128”。例如:

>>> u'Cerón'.encode('ascii')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf3' in position 3:
 ordinal not in range(128)

如果您使用str(u'Cerón'),也会发生同样的情况,因为默认情况下Python使用 ascii unicode转换为str

要使其工作,您必须使用不同的编码格式。 UTF-8 是一种编码格式,可以将任何unicode文本表示为字节。要将u'Cerón' unicode字符串转换为必须使用的字节:

>>> u'Cerón'.encode('utf-8')
'Cer\xc3\xb3n'

这次没有错误。

现在,回到您的电子邮件问题。我可以看到您正在使用MIMEText,它接受​​已编码的str参数,在您的情况下是html变量。 MIMEText还接受一个参数,指定正在使用的编码类型。因此,在您的情况下,如果html是一个unicode字符串,则必须将其编码为utf-8并传递charset参数(因为HTMLText默认使用ascii):

part1 = MIMEText(html.encode('utf-8'), 'html', 'utf-8')

但要小心,因为如果html已经是str而不是unicode,则编码将失败。这是Python 2.x的问题之一,它允许您对已编码的字符串进行编码,但它会引发错误。

添加到列表中的另一个问题是 utf-8 ascii 字符兼容,Python将始终尝试使用自动编码/解码字符串ASCII 。如果您没有正确编码字符串,但只使用 ascii 字符,那么一切都会正常工作。但是,如果由于某种原因某些非ascii 字符滑入您的邮件,您将收到错误,这会使错误更难以检测。

答案 2 :(得分:0)

请记住:您无法解码unicode,也无法编码str

>>> u"\xa0".decode("ascii", "ignore")

Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    u"\xa0".decode("ascii", "ignore")
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 0: ordinal not in range(128)


>>> "\xc2".encode("ascii", "ignore")

Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    "\xc2".encode("ascii", "ignore")
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 0: ordinal not in range(128)

结帐这个优秀的tutorial