假设您使用的是 Python 2.x,请记住:有两种类型的字符串:str
和unicode
. str
是字节字符串,而是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
已经是 astr
而不是unicode
,那么编码将失败。这是 Python 2.x 的问题之一,它允许您对已经编码的字符串进行编码,但会引发错误。
要添加到列表中的另一个问题是utf-8与ascii字符兼容,Python 将始终尝试使用ascii自动编码/解码字符串。如果你没有正确编码你的字符串,但你只使用ascii字符,一切都会正常工作。但是,如果由于某种原因某些非 ascii字符滑入您的消息中,您将收到错误,这使得错误更难检测。