str
Python 2.x を使用していると仮定すると、文字列には と の 2 種類があることを思い出してくださいunicode
。str
はバイト文字列unicode
ですが、Unicode 文字列です。unicode
文字列は任意の言語でテキストを表すために使用できますが、テキストをコンピューターに保存したり、電子メールで送信したりするには、そのテキストをバイトで表す必要があります。バイトを使用してテキストを表現するには、コーディング形式が必要です。多くのコーディング形式があり、Python はデフォルトでasciiを使用しますが、 asciiはほとんどが英字の少数の文字しか表現できません。asciiを使用してテキストを他の文字でエンコードしようとすると、有名な "outside ordinal 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 はデフォルトでasciiunicode
を使用して に変換するため、を使用する場合も同じことが起こりますstr
。
これを機能させるには、別のコーディング形式を使用する必要があります。UTF-8は、任意の Unicode テキストをバイトとして表現できるコーディング形式です。u'Cerón'
ユニコード文字列をバイトに変換するには、次を使用する必要があります。
>>> 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 の問題の 1 つで、既にエンコードされた文字列をエンコードできますが、エラーがスローされます。
リストに追加するもう 1 つの問題は、utf-8がascii文字と互換性があり、Python は常にasciiを使用して文字列を自動的にエンコード/デコードしようとすることです。文字列を適切にエンコードしていなくても、ASCII文字のみを使用している場合、問題なく動作します。ただし、何らかの理由でASCII以外の文字がメッセージに含まれていると、エラーが発生し、エラーの検出が難しくなります.