この記事では、「Ha」を例としてすべての問題を説明します。「Ha」のさまざまなエンコーディングは次のとおりです。
1. UNICODE (UTF8-16)、
2。 UTF-8、E59388; 3. GBK、B9FE。
1. Python の str と unicode
長い間、Python の中国語エンコーディングは非常に大きな問題であり、エンコーディング変換例外が頻繁にスローされます。Python の str と unicode とは何ですか?
Python で Unicode という場合、通常は Unicode オブジェクトを指します。たとえば、「haha」の Unicode オブジェクトは
u'u54c8u54c8' です。
このバイト配列は Unicode オブジェクトのエンコーディングを表します。 utf-8、gbk、cp936、GB2312 以降のストレージ形式を使用できます。ここでは、これは単なるバイト ストリームであり、他の意味はありません。このバイト ストリームによって表示されるコンテンツを意味のあるものにしたい場合は、正しいエンコード形式を使用してデコードし、表示する必要があります。
例:
上記のデモ コードに示すように:
UnicodeEncodeError: 'gbk' コーデックは位置 0 で文字 u'ufeff' をエンコードできません: 不正なマルチバイト シーケンス
メモ帳などの一部のソフトウェアでは、UTF-8 でエンコードされたファイルを保存すると、最終的にファイルの先頭に 3 つの非表示文字 (0xEF 0xBB 0xBF、BOM) を挿入します。
そのため、読み取り時にこれらの文字を自分で削除する必要があります。Python の codecs モジュールは次の定数を定義します:
#coding=gbk
import codecs
data = open("Test.txt").read()
if data[:3] == codecs.BOM_UTF8:
data = data[3:]
print data.decode("utf-8")
結果: abc Chinese
5. ファイルエンコード形式と役割エンコーディング宣言の
ソースファイルのエンコーディング形式は文字列の宣言にどのような影響を与えますか?この問題は長い間私を悩ませてきましたが、今ようやくいくつかの手がかりが得られました。ファイルのエンコード形式によって、ソース ファイルで宣言された文字列のエンコード形式が決まります。たとえば、次のようになります。 print repr(str)
a. ファイル形式が utf-8 の場合、str の値は次のとおりです: 'xe5x93x88xe5x93x88' (haha の utf-8 エンコーディング)
b. ファイル形式が gbk の場合、str の値は次のようになります。 : 'xb9xfexb9xfe' (笑 gbkエンコード)
最初のセクションでも述べたように、Pythonの文字列は単なるバイト配列であるため、aの場合のstrをgbkエンコードコンソールに出力すると文字化けして表示されます。 :鍝埚搱; そして、ケースbのstrをutf-8エンコードされたコンソールに出力すると、文字化けの問題も表示され、おそらくutf-8デコードを使用して「xb9xfexb9xfe」が表示されます。そして空白になります。 >_<
ファイル形式について説明した後、各ファイルの先頭で #coding=gbk のようなステートメントを使用してエンコーディングを宣言します。この文の?これまでのところ、これには 3 つの機能があると思います:
非 ASCII エンコーディングがソース ファイル (通常は中国語) に表示されることを示します。
高度な IDE では、IDE は指定したエンコーディング形式でファイル形式を保存します。
ソースコード内の u'ha' のような宣言で 'ha' を Unicode にデコードするために使用されるエンコード形式の決定も、混乱を招く場所です。例を参照してください:
#coding:gbk
print repr(ss)
print 'ss:%s' % ss
これらのコードを utf-8 テキストに保存して実行すると、何が出力されると思いますか?誰もが出力は次のようになったはずです:
u'u54c8u54c8'
ss: はは
しかし、実際の出力は:
u'u935du581du6431'
ss:埚搱
なぜこれが起こっているのでしょうか? ss = u'haha' を実行する場合、プロセス全体は次のステップに分割できます:
1) 'haha' のエンコーディングを取得します。ファイルのエンコーディング形式によって決まります。は 'xe5x93x88xe5x93x88' (母の utf-8 エンコード形式) です
2) Unicode エンコードに変換するとき、この変換プロセス中に、「xe5x93x88xe5x93x88」のデコードは utf-8 ではなく、宣言で指定されたエンコード GBK でデコードされます。エンコードし、GBK に従って 'xe5x93x88xe5x93x88' をデコードし、 '鍝韚搱' を取得します。これらの 3 文字の Unicode エンコードは u'u935du581du6431' であり、これが print repr(ss) が u'u935du581du6431' を出力する理由の説明になります。
わかりました、これは少しわかりにくいので、次の例を分析してみましょう:
#-*-coding:utf-8 -*-
ss = u'haha'
print repr(ss)
print 'ss :%s' % ss
今回はこの例を GBK エンコードに保存します。実行結果は次のようになります。
UnicodeDecodeError: 'utf8' コーデックは位置 0 のバイト 0xb9 をデコードできません: 予期しないコード バイト
なぜここにあるのでしょうか? utf8デコードエラーはありますか?前の例を考えると、変換の最初のステップでは、ファイルのエンコーディングが GBK であるため、変換時に得られるエンコーディングは「haha」になります。これは、GBK エンコーディングの「xb9xfexb9xfe」です。 Unicode に変換するには、UTF8 が使用されます。「xb9xfexb9xfe」をデコードし、utf-8 エンコード テーブルを確認すると、utf8 エンコード テーブルにまったく存在しないことがわかります (UTF-8 の説明については、を参照してください)。文字エンコーディングに注意してください: ASCII、UTF-8、UNICODE)、上記のエラーが報告されます。
Python の中国語文字化け問題の詳細な分析と関連記事については、PHP 中国語 Web サイトに注目してください。