python中国語のエンコーディング問題を詳しく説明します。
1. Pythonでは中国語を使います。
Pythonにはデフォルトの文字列が二つあります。strとunicode。Pythonでは、「Unicode文字列」と「unicodeオブジェクト」の違いに注意してください。後ろの「unicode文字列」は全部pythonの「unicodeオブジェクト」を指します。
実際にPythonには「Unicode文字列」というものはなく、「unicode」の対象だけです。伝統的な意味でunicode文字列はstrオブジェクトで完全に表現できます。ただし、この時点では単にバイトストリームであり、unicodeオブジェクトとして復号しない限り、実用的な意味はない。
私たちは「はは」を使って複数のプラットフォームでテストします。その中で「は」の対応する異なるコードは:
1. UNICODE(UTF 8-16)は、 C 854;
2. UTF-8、 E 59388;
3. GBK、 B 9 FEです。
1.1 Windowsコンソール
次はwindowsコンソールでの運行結果です。
コンソールでは、中国語の文字はUTF-16ではなくGBKであることが分かります。文字列s(GBK符号化)をデコードすると、同等のunicodeオブジェクトが得られます。
注意:コンソールでssを印刷することができますが、それを表していません。
ファイルに直接出力すると同じ異常が発生します。unicode中国語文字列を処理する時、まずencode関数を呼び出して、他の符号化出力に変換しなければなりません。この点はそれぞれの環境に対して同じです。
まとめ:Pythonでは、「str」オブジェクトはバイト配列であり、中身は合法的な文字列ではなく、この文字列はどのような符号化(gbk,utf-8,unicode)を採用するかは重要ではない。これらの内容はユーザー自身の記録と判断が必要です。これらの制限は、「unicode」オブジェクトにも適用されます。「unicode」の対象の内容を覚えておくと絶対に合法的なunicode文字列とは限りません。私たちはすぐにこのような状況を見ます。
まとめ:windowsのコンソールで、gbkコードのstrオブジェクトとunicodeコードのunicodeオブジェクトをサポートします。
1.2 Windows IDLE(Shell上で実行)
windows下のIDLEでは、運行効果とwindowsコンソールは完全に一致していません。
これにより、「u」を使用しないで識別する文字列に対して、IDLEはその中の中国語文字をGBK符号化することができる。しかし、「u」を使ったunicode文字列に対して、IDLEは同じGBKコードを使っています。違いは、この時の各文字はunicode文字です。このときlen(ss)=4です。
このように不思議な問題が発生して、今のssはIDLEの中で正常に表示することができません。それに、ssを正常なコードに変換する方法がありません。たとえば、次のような方法を採用します。
IDLEのローカル化が足りないため、中国語のサポートに問題があるかもしれません。IDLEのSHELLでは、uの「中国語」は使わないことをお勧めします。
これは同時に、IDLEのShellは2つのフォーマットの中国語文字列をサポートしています。GBK符号化された「str」オブジェクトと、UNCODE符号化されたunicodeオブジェクトです。
1.3 IDLEでコードを実行
IDLEのSHELLでファイルを実行すると、また違った結果が得られます。ファイルの内容は:
直接運転の結果は:
瑕疵のない、かなり満足です。他のコードのファイルが正常に動作するかどうか試したことがありませんが、いいと思います。
同じコードはwindowsのコンソールで試演したことがあります。何の問題もありません。
1.4 Windows Eclipse
Eclipseで中国語を処理するのはもっと難しいです。Eclipseではコードの作成と実行コードは異なるウィンドウに属しています。そして、デフォルトのコードがあります。以下のコードについて:
'/xe 5/x 93/x 88/xe 5/x 93/x 88'
u'/u 54 c 8/u 54 c 8'
はははは
はははは
Traceback(most recent call last):
File「E:/Workspace/Eclipse/TestPython/Test/test_encoding.2.py「ライン13、in<module>」
print s.decode('utf-8')
Unicode EncodeError:'ascii'codec can't encode characters in position 0-1:ordinal not in range(128)
つまり、GBKコードのstrオブジェクトは正常に印刷できますが、UNIcodeコードのunicodeオブジェクトは印刷できません。ソースファイルで「Run as」「Run」をクリックし、ポップアップダイアログで「Common」を選択します。
Eclipseコンソールのデフォルトコード方式はGBKであることが分かります。だからユニコムを支持しないのも無理はない。文書中のcodingをGBKに変更すると、GBK符号化のstrオブジェクト、例えばsを直接印刷することができる。
ソースファイルの符号化を「UTF-8」に設定すれば、コンソールの符号化も「UTF-8」に設定されていますので、当然プリントする時は大丈夫です。しかし、UTF-8のコード化されたstrオブジェクトを印刷すると、中国語の最後の文字が文字化けして表示され、正常に読めないことが実験で明らかになった。でも、私はもう満足しています。少なくとも、人が異常を投げていません。
BTW:使うEclipseバージョンは3.2.1です。
1.5 ファイルから中国語を読み込みます。
windowの下でメモ帳でファイルを編集する場合、UNICODEまたはUTF-8として保存すると、それぞれファイルの先頭に2バイトの「/xFF/xFE」と3バイトの「/xEF/xBB/xBF」を追加します。読み取り時に問題があるかもしれませんが、環境によってはこれらの多文字に対する処理が異なります。
windowsの下のコンソールを例にとって、メモ帳で三つの異なるバージョンの「はは」を保存します。
utf-8形式のファイルを開き、utf-8文字列を読み込むと、unicodeオブジェクトとなります。ただし、追加された3つの文字を同じように変換してunicode文字にします。文字のデータ値は「/xFF/xFE」です。この文字は印刷できません。エンコードするときはこの文字をスキップする必要があります。
unicode形式のファイルを開くと、正しい文字列が得られます。この場合はutf-16復号が適用され、正確なunicdoeオブジェクトが得られます。直接使用できます。余分な充填文字は変換時にフィルタされます。
ansi形式のファイルを開くと、塗りつぶしなしでそのまま使用できます。
結論:pythonを使って生成されたファイルを読み書きするのは問題ないですが、notepadによって生成されたテキストファイルを処理する場合、このファイルが非ansi符号化かもしれない場合、パディング文字をどのように処理するかを考慮する必要があります。
1.6 データベースで中国語を使う
Pythonに接触したばかりです。私が使っているデータベースはmysqlです。挿入、検索などの操作を行う場合、動作環境で使用する文字コードとmysqlが一致しないと、運転時のエラーを引き起こす可能性があります。もちろん、上で見た状況と同じです。運行環境は重要な要素ではなく、キーは照会文の符号化方式です。クエリー操作を行うたびに、クエリ文字列を一度にエンコードして変換すれば、mysqlのデフォルト文字コードに変わります。同じように問題がありません。でも、コードを書くのもつらいですよね。
次のコードを使ってデータベースに接続します。
1.7 XMLで中国語を使う
xml.dom.minidomを使ってMySQLdbと同様に、生成したdomオブジェクトに対してtoxml方法を呼び出すとunicodeオブジェクトが得られます。utf-8テキストを出力したい場合、2つの方法があります。
1.システム関数を使う
xmlドキュメントを出力する時にコーディングするのが一番いいと思います。
toxmlを使用した後、encodeメソッドを呼び出してドキュメントをエンコードすることができます。しかし、この方法は適切なxml declaration(xmlドキュメントの最初の行のencoding部分)を得ることができません。
xmldoc.reat Processing Instructionを通じてプロシーションを作成しないでください。
相面は二つの方法の使い方の比較です。
また、IDLEのshellでは、u'中国語'で属性を付与しないでください。上記で検討しましたが、このようにして得られたunicode文字列は正しくありません。
ここでpython中国語の符号化問題についての文章を紹介します。中国語のコードの内容については以前の文章を検索してください。または下記の関連記事を引き続き閲覧してください。これからもよろしくお願いします。
Pythonにはデフォルトの文字列が二つあります。strとunicode。Pythonでは、「Unicode文字列」と「unicodeオブジェクト」の違いに注意してください。後ろの「unicode文字列」は全部pythonの「unicodeオブジェクト」を指します。
実際にPythonには「Unicode文字列」というものはなく、「unicode」の対象だけです。伝統的な意味でunicode文字列はstrオブジェクトで完全に表現できます。ただし、この時点では単にバイトストリームであり、unicodeオブジェクトとして復号しない限り、実用的な意味はない。
私たちは「はは」を使って複数のプラットフォームでテストします。その中で「は」の対応する異なるコードは:
1. UNICODE(UTF 8-16)は、 C 854;
2. UTF-8、 E 59388;
3. GBK、 B 9 FEです。
1.1 Windowsコンソール
次はwindowsコンソールでの運行結果です。
コンソールでは、中国語の文字はUTF-16ではなくGBKであることが分かります。文字列s(GBK符号化)をデコードすると、同等のunicodeオブジェクトが得られます。
注意:コンソールでssを印刷することができますが、それを表していません。
ファイルに直接出力すると同じ異常が発生します。unicode中国語文字列を処理する時、まずencode関数を呼び出して、他の符号化出力に変換しなければなりません。この点はそれぞれの環境に対して同じです。
まとめ:Pythonでは、「str」オブジェクトはバイト配列であり、中身は合法的な文字列ではなく、この文字列はどのような符号化(gbk,utf-8,unicode)を採用するかは重要ではない。これらの内容はユーザー自身の記録と判断が必要です。これらの制限は、「unicode」オブジェクトにも適用されます。「unicode」の対象の内容を覚えておくと絶対に合法的なunicode文字列とは限りません。私たちはすぐにこのような状況を見ます。
まとめ:windowsのコンソールで、gbkコードのstrオブジェクトとunicodeコードのunicodeオブジェクトをサポートします。
1.2 Windows IDLE(Shell上で実行)
windows下のIDLEでは、運行効果とwindowsコンソールは完全に一致していません。
これにより、「u」を使用しないで識別する文字列に対して、IDLEはその中の中国語文字をGBK符号化することができる。しかし、「u」を使ったunicode文字列に対して、IDLEは同じGBKコードを使っています。違いは、この時の各文字はunicode文字です。このときlen(ss)=4です。
このように不思議な問題が発生して、今のssはIDLEの中で正常に表示することができません。それに、ssを正常なコードに変換する方法がありません。たとえば、次のような方法を採用します。
IDLEのローカル化が足りないため、中国語のサポートに問題があるかもしれません。IDLEのSHELLでは、uの「中国語」は使わないことをお勧めします。
これは同時に、IDLEのShellは2つのフォーマットの中国語文字列をサポートしています。GBK符号化された「str」オブジェクトと、UNCODE符号化されたunicodeオブジェクトです。
1.3 IDLEでコードを実行
IDLEのSHELLでファイルを実行すると、また違った結果が得られます。ファイルの内容は:
直接運転の結果は:
瑕疵のない、かなり満足です。他のコードのファイルが正常に動作するかどうか試したことがありませんが、いいと思います。
同じコードはwindowsのコンソールで試演したことがあります。何の問題もありません。
1.4 Windows Eclipse
Eclipseで中国語を処理するのはもっと難しいです。Eclipseではコードの作成と実行コードは異なるウィンドウに属しています。そして、デフォルトのコードがあります。以下のコードについて:
#!/usr/bin/python
# -*- coding: utf-8 -*-
s = " "
ss = u' '
print repr(s)
print repr(ss)
print s.decode('utf-8').encode('gbk')
print ss.encode('gbk')
print s.decode('utf-8')
print ss
前の4つのprintは正常に運行しています。最後の二つのprintは異常を投げます。'/xe 5/x 93/x 88/xe 5/x 93/x 88'
u'/u 54 c 8/u 54 c 8'
はははは
はははは
Traceback(most recent call last):
File「E:/Workspace/Eclipse/TestPython/Test/test_encoding.2.py「ライン13、in<module>」
print s.decode('utf-8')
Unicode EncodeError:'ascii'codec can't encode characters in position 0-1:ordinal not in range(128)
つまり、GBKコードのstrオブジェクトは正常に印刷できますが、UNIcodeコードのunicodeオブジェクトは印刷できません。ソースファイルで「Run as」「Run」をクリックし、ポップアップダイアログで「Common」を選択します。
Eclipseコンソールのデフォルトコード方式はGBKであることが分かります。だからユニコムを支持しないのも無理はない。文書中のcodingをGBKに変更すると、GBK符号化のstrオブジェクト、例えばsを直接印刷することができる。
ソースファイルの符号化を「UTF-8」に設定すれば、コンソールの符号化も「UTF-8」に設定されていますので、当然プリントする時は大丈夫です。しかし、UTF-8のコード化されたstrオブジェクトを印刷すると、中国語の最後の文字が文字化けして表示され、正常に読めないことが実験で明らかになった。でも、私はもう満足しています。少なくとも、人が異常を投げていません。
BTW:使うEclipseバージョンは3.2.1です。
1.5 ファイルから中国語を読み込みます。
windowの下でメモ帳でファイルを編集する場合、UNICODEまたはUTF-8として保存すると、それぞれファイルの先頭に2バイトの「/xFF/xFE」と3バイトの「/xEF/xBB/xBF」を追加します。読み取り時に問題があるかもしれませんが、環境によってはこれらの多文字に対する処理が異なります。
windowsの下のコンソールを例にとって、メモ帳で三つの異なるバージョンの「はは」を保存します。
utf-8形式のファイルを開き、utf-8文字列を読み込むと、unicodeオブジェクトとなります。ただし、追加された3つの文字を同じように変換してunicode文字にします。文字のデータ値は「/xFF/xFE」です。この文字は印刷できません。エンコードするときはこの文字をスキップする必要があります。
unicode形式のファイルを開くと、正しい文字列が得られます。この場合はutf-16復号が適用され、正確なunicdoeオブジェクトが得られます。直接使用できます。余分な充填文字は変換時にフィルタされます。
ansi形式のファイルを開くと、塗りつぶしなしでそのまま使用できます。
結論:pythonを使って生成されたファイルを読み書きするのは問題ないですが、notepadによって生成されたテキストファイルを処理する場合、このファイルが非ansi符号化かもしれない場合、パディング文字をどのように処理するかを考慮する必要があります。
1.6 データベースで中国語を使う
Pythonに接触したばかりです。私が使っているデータベースはmysqlです。挿入、検索などの操作を行う場合、動作環境で使用する文字コードとmysqlが一致しないと、運転時のエラーを引き起こす可能性があります。もちろん、上で見た状況と同じです。運行環境は重要な要素ではなく、キーは照会文の符号化方式です。クエリー操作を行うたびに、クエリ文字列を一度にエンコードして変換すれば、mysqlのデフォルト文字コードに変わります。同じように問題がありません。でも、コードを書くのもつらいですよね。
次のコードを使ってデータベースに接続します。
self.conn = MySQLdb.connect(use_unicode = 1, charset='utf8', **server)
理解できないのは、データベース用のデフォルトコードがUTF-8である以上、私が接続する時もUTF-8を使っていますが、なぜ検索されたテキストの内容はUNIcodeコードですか?これはMySQLdbライブラリの設定ですか?1.7 XMLで中国語を使う
xml.dom.minidomを使ってMySQLdbと同様に、生成したdomオブジェクトに対してtoxml方法を呼び出すとunicodeオブジェクトが得られます。utf-8テキストを出力したい場合、2つの方法があります。
1.システム関数を使う
xmlドキュメントを出力する時にコーディングするのが一番いいと思います。
xmldoc.toxml(encoding='utf-8')
xmldoc.writexml(outfile, encoding = ‘utf-8')
2.自己コード生成toxmlを使用した後、encodeメソッドを呼び出してドキュメントをエンコードすることができます。しかし、この方法は適切なxml declaration(xmlドキュメントの最初の行のencoding部分)を得ることができません。
xmldoc.reat Processing Instructionを通じてプロシーションを作成しないでください。
<?xml version='1.0' encoding='utf-8'?>
xml declarationは似ていますが、実際にはプロモーションではありません。次の方法で満足できるxmlファイルが得られます。
print >> outfile, “<?xml version='1.0' encoding='utf-8'?>”
print >> outfile, xmldoc.toxml().encode(‘utf-8')[22:]
その中の二行目はxmldoc.toxmlを呼び出した時に発生した「<?xml version='1.0'?"その長さは22です。相面は二つの方法の使い方の比較です。
また、IDLEのshellでは、u'中国語'で属性を付与しないでください。上記で検討しましたが、このようにして得られたunicode文字列は正しくありません。
ここでpython中国語の符号化問題についての文章を紹介します。中国語のコードの内容については以前の文章を検索してください。または下記の関連記事を引き続き閲覧してください。これからもよろしくお願いします。