python文字コードの詳細
本文は転載してから[http://www.cnblogs.com/huxi/archive/2010/12/05/1897271.html」というように、一般的な文字コードの特徴を簡単に紹介し、python 2.xで符号化問題とどのように戦うかを紹介しました.
本文のPythonに関する内容は2.x、3.xの中のstrとunicodeにのみ適用されます.他の関連文書を参照してください.文字コードプロファイル1.1.ASCII ASCIIは、シングルバイトのコードです.コンピュータの世界では最初は英語だけでしたが、シングルバイトは256の異なる文字を表しています.すべての英字と多くの制御記号を表しています.しかし、ASCIIはその半分(\x 80以下)しか使われませんでした.これもMBCSの実現の基礎です.1.2.MBCS
しかし、コンピュータの世界には他の言語があります.バイトのASCIIはもう需要を満たすことができません.その後、各言語は自分のコードを制定しました.単バイトで表現できる文字が少なすぎて、ASCIIコードと互換性が必要です.だから、これらのコードは多くのバイトを使って文字を表しています.例えば、GBxxx、BIGxxxなどです.彼らのルールは、最初のバイトが\x 80以下なら、ASCII文字を表しています.一方、\x 80以上であれば、次のバイトと一緒に1文字を表し、次のバイトをスキップして判定を続けます.
ここで、IBMはCode Pageという概念を発明し、これらのコードをすべて袋に入れてページ番号を割り当て、GBKは936ページ目、つまりCP 936です.したがって、CP936を使用してGBKを表すこともできる.
MBCS(Multi-Byte Charcter Set)はこれらの符号化の総称である.これまでは二バイトを使っていたので、DBCS(Duble-Byte Charcter Set)とも呼ばれることがあります.明確にしなければならないのは、MBCSは特定のコードではなく、Windowsではあなたが設定したエリアによってMBCSは異なるコードを指していますが、LinuxではMBCSはコードとして使用できません.WindowsではMBCSという文字は見られません.マイクロソフトはもっと洋風にするためにANSIを使って人を脅かしています.メモ帳の保存はダイアログでANSIをエンコードするのがMBCSです.また、簡体字中国語Windowsのデフォルトのエリア設定では、GBKを指す.1.3.ユニックode
その後、コードが多すぎて世界が複雑になりすぎて、頭が痛くなりました.みんなで座って頭をたたいて、一つの方法を思い出しました.すべての言語の文字は同じ文字セットで表しています.これはユニックです.
最初のUnicode標準UCS-2は2バイトを使って一つの文字を表していますので、ユニックは2バイトを使って一つの文字を表すという話をよく聞きます.しかし、そのうち256*256が少なすぎて、まだ足りないという人がいます.そこでUCS-4標準が現れました.4バイトを使って一つの文字を表しますが、一番多く使うのはやはりUCS-2です.
UCSはまだ文字対応コードビットの一枚の表にすぎません.たとえば「漢」という文字の符号位は6 C 49です.文字の具体的な伝達と保存はUTF(UCS Transformation Format)が担当します.
最初のことは簡単で、UCSのコードビットを直接使って保存します.これはUTF-16です.例えば、「漢」は直接\x 6 C\x 49を使って保存します.しかし、アメリカ人を使って自分が大損をしたと感じています.以前は英字は一バイトで保存できましたが、今は大鍋ご飯を食べたら二バイトになり、空間の消耗が倍になりました.
UTF-8はとてもこじれた符号で、具体的には彼が長くなることを表しています.ASCIIに対応しています.ASCII文字は1バイトの表現を使います.しかし、ここで節約したのは他のところから掘り出したものに違いないです.UTF-8で中国語の文字を3バイト使って保存するという話も聞いたことがありますよね?4バイト保存の文字は涙の中で走ります.
ちなみに、BOMです.私たちはファイルを保存する時に、ファイルのコードを保存していません.開く時は、保存時に使っていたコードを覚えて、このコードを使って開けてください.そうすると、多くのトラブルが発生します.(メモ帳がファイルを開く時に、選択コードを開けていないと言ってもいいですか?メモ帳を開けてからファイルを使ってみてください.)UTFは自分のコードをBOMに導入しています.最初に読み込むバイトがその中の一つであれば、次に読み込む文字を表すコードは該当符号です.
BOMUTF 8'\xef\xbb\xbf'BOM_UTF 16_LE'\xff\xfe'BOM_UTF 16_BE'\xfe\xff'
すべてのエディタがBOMに書き込むわけではありませんが、BOMがなくてもUnicodeは読み込むことができます.MBCSのコードのように、別に具体的なコードを指定する必要があります.そうでないと復号は失敗します.
UTF-8はBOMを必要としないと聞いたことがあるかもしれませんが、ほとんどのエディタはBOMがない時はUTF-8をデフォルトコードとして読みます.保存時にはデフォルトでANSI(MBCS)のメモ帳を使用しても、ファイルを読み込む時にはUTF-8を使って符号化をテストし、うまく復号できるならUTF-8を使って復号します.メモ帳のこのこじれたやり方はBUGをもたらしました.もしあなたがテキストファイルを新築して入力したら、「塧塧塧」を使ってANSI(MBCS)を使って保存して、また開くと「漢a」になります.試してみてください.) Python 2.xにおける符号化問題2.1.strとunicode strとunicodeはすべてbasestringのサブクラスです.厳密には、strはバイト列であり、unicodeがコード化されたバイトからなるシーケンスである.UTF-8符号化のstr’漢’にlen()関数を使用した場合、結果は3です.実は、UTF-8符号化の'漢'='\xE 6\xB 1\x 89'.
unicodeこそ本当の意味での文字列です.バイトストリングは正しい文字コードを使って復号して得られます.len(u'漢')=1です.
encode()とdecode()の二つのbasestringの実例的な方法を見てみてください.strとunicodeの違いを理解したら、この二つの方法は混同しなくなります.
coding:UTF-8
u=u'h'h's=u.encode print repr('UTF-8')print repr(s)咻咻\xb 1\x 89'u 2=s.decode('UTF-8')print repr(u 2)
unicodeを復号するのはエラーです.
s 2=u.decode('UTF-8')
同様に、strを符号化するのも間違っています.
u 2=s.encode('UTF-8')
本文のPythonに関する内容は2.x、3.xの中のstrとunicodeにのみ適用されます.他の関連文書を参照してください.
しかし、コンピュータの世界には他の言語があります.バイトのASCIIはもう需要を満たすことができません.その後、各言語は自分のコードを制定しました.単バイトで表現できる文字が少なすぎて、ASCIIコードと互換性が必要です.だから、これらのコードは多くのバイトを使って文字を表しています.例えば、GBxxx、BIGxxxなどです.彼らのルールは、最初のバイトが\x 80以下なら、ASCII文字を表しています.一方、\x 80以上であれば、次のバイトと一緒に1文字を表し、次のバイトをスキップして判定を続けます.
ここで、IBMはCode Pageという概念を発明し、これらのコードをすべて袋に入れてページ番号を割り当て、GBKは936ページ目、つまりCP 936です.したがって、CP936を使用してGBKを表すこともできる.
MBCS(Multi-Byte Charcter Set)はこれらの符号化の総称である.これまでは二バイトを使っていたので、DBCS(Duble-Byte Charcter Set)とも呼ばれることがあります.明確にしなければならないのは、MBCSは特定のコードではなく、Windowsではあなたが設定したエリアによってMBCSは異なるコードを指していますが、LinuxではMBCSはコードとして使用できません.WindowsではMBCSという文字は見られません.マイクロソフトはもっと洋風にするためにANSIを使って人を脅かしています.メモ帳の保存はダイアログでANSIをエンコードするのがMBCSです.また、簡体字中国語Windowsのデフォルトのエリア設定では、GBKを指す.1.3.ユニックode
その後、コードが多すぎて世界が複雑になりすぎて、頭が痛くなりました.みんなで座って頭をたたいて、一つの方法を思い出しました.すべての言語の文字は同じ文字セットで表しています.これはユニックです.
最初のUnicode標準UCS-2は2バイトを使って一つの文字を表していますので、ユニックは2バイトを使って一つの文字を表すという話をよく聞きます.しかし、そのうち256*256が少なすぎて、まだ足りないという人がいます.そこでUCS-4標準が現れました.4バイトを使って一つの文字を表しますが、一番多く使うのはやはりUCS-2です.
UCSはまだ文字対応コードビットの一枚の表にすぎません.たとえば「漢」という文字の符号位は6 C 49です.文字の具体的な伝達と保存はUTF(UCS Transformation Format)が担当します.
最初のことは簡単で、UCSのコードビットを直接使って保存します.これはUTF-16です.例えば、「漢」は直接\x 6 C\x 49を使って保存します.しかし、アメリカ人を使って自分が大損をしたと感じています.以前は英字は一バイトで保存できましたが、今は大鍋ご飯を食べたら二バイトになり、空間の消耗が倍になりました.
UTF-8はとてもこじれた符号で、具体的には彼が長くなることを表しています.ASCIIに対応しています.ASCII文字は1バイトの表現を使います.しかし、ここで節約したのは他のところから掘り出したものに違いないです.UTF-8で中国語の文字を3バイト使って保存するという話も聞いたことがありますよね?4バイト保存の文字は涙の中で走ります.
ちなみに、BOMです.私たちはファイルを保存する時に、ファイルのコードを保存していません.開く時は、保存時に使っていたコードを覚えて、このコードを使って開けてください.そうすると、多くのトラブルが発生します.(メモ帳がファイルを開く時に、選択コードを開けていないと言ってもいいですか?メモ帳を開けてからファイルを使ってみてください.)UTFは自分のコードをBOMに導入しています.最初に読み込むバイトがその中の一つであれば、次に読み込む文字を表すコードは該当符号です.
BOMUTF 8'\xef\xbb\xbf'BOM_UTF 16_LE'\xff\xfe'BOM_UTF 16_BE'\xfe\xff'
すべてのエディタがBOMに書き込むわけではありませんが、BOMがなくてもUnicodeは読み込むことができます.MBCSのコードのように、別に具体的なコードを指定する必要があります.そうでないと復号は失敗します.
UTF-8はBOMを必要としないと聞いたことがあるかもしれませんが、ほとんどのエディタはBOMがない時はUTF-8をデフォルトコードとして読みます.保存時にはデフォルトでANSI(MBCS)のメモ帳を使用しても、ファイルを読み込む時にはUTF-8を使って符号化をテストし、うまく復号できるならUTF-8を使って復号します.メモ帳のこのこじれたやり方はBUGをもたらしました.もしあなたがテキストファイルを新築して入力したら、「塧塧塧」を使ってANSI(MBCS)を使って保存して、また開くと「漢a」になります.試してみてください.)
unicodeこそ本当の意味での文字列です.バイトストリングは正しい文字コードを使って復号して得られます.len(u'漢')=1です.
encode()とdecode()の二つのbasestringの実例的な方法を見てみてください.strとunicodeの違いを理解したら、この二つの方法は混同しなくなります.
coding:UTF-8
u=u'h'h's=u.encode print repr('UTF-8')print repr(s)咻咻\xb 1\x 89'u 2=s.decode('UTF-8')print repr(u 2)
unicodeを復号するのはエラーです.
s 2=u.decode('UTF-8')
同様に、strを符号化するのも間違っています.
u 2=s.encode('UTF-8')
, str encode() , Python , id str; unicode decode() 。 encode() decode() unicode str basestring , , 。
2.2.
, ASCII , , :
#-*- coding: UTF-8 -*-
Python #、coding , 。 ,Python , , , UTF-8 u8。 [http://docs.python.org/library/codecs.html#standard-encodings]。
, 。 IDE , , :)
2.3.
open() ,read() str, decode()。write() , unicode, encode(), str, str decode(), unicode encode()。 unicode write() ,Python 。
# coding: UTF-8
f = open('test.txt')
s = f.read()
f.close()
print type(s) #
# GBK , unicode
u = s.decode('GBK')
f = open('test.txt', 'w')
# UTF-8 str
s = u.encode('UTF-8')
f.write(s)
f.close()
, codecs open() , , unicode。 , unicode, open() ; str, , unicode 。 open() , 。
# coding: GBK
import codecs
f = codecs.open('test.txt', encoding='UTF-8')
u = f.read()
f.close()
print type(u) #
f = codecs.open('test.txt', 'a', encoding='UTF-8')
# unicode
f.write(u)
# str,
# GBK str
s = ' '
print repr(s) # '\xba\xba'
# GBK str unicode UTF-8
f.write(s)
f.close()
2.4.
sys/locale 。
# coding:gbk
import sys
import locale
def p(f):
print '%s.%s(): %s' % (f.__module__, f.__name__, f())
#
p(sys.getdefaultencoding)
# Unicode
p(sys.getfilesystemencoding)
# ( , )
p(locale.getdefaultlocale)
#
# this function only returns a guess
p(locale.getpreferredencoding)
# \xba\xba ' ' GBK
# mbcs ,
print r"'\xba\xba'.decode('mbcs'):", repr('\xba\xba'.decode('mbcs'))
# Windows ( ( , ))
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp936')
#locale.getpreferredencoding(): cp936
#'\xba\xba'.decode('mbcs'): u'\u6c49'
3.
3.1. , 。
。
3.2. str, unicode。
u , 90% 。 , 。
3.3. codecs.open() open()。
, 。
3.4. :MBCS/DBCS UTF-16。
MBCS GBK , Python ’MBCS’ , 。
Python ’MBCS’ ’DBCS’ , Windows MBCS 。Linux Python , Linux ! , Windows ,MBCS 。 2.4 :
# ( , )
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp936')
#locale.getpreferredencoding(): cp936
#'\xba\xba'.decode('mbcs'): u'\u6c49'
# ( )
#sys.getdefaultencoding(): UTF-8
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp1252')
#locale.getpreferredencoding(): cp1252
#'\xba\xba'.decode('mbcs'): u'\xba\xba'
# ( )
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp1252')
#locale.getpreferredencoding(): cp1252
#'\xba\xba'.decode('mbcs'): u'\xba\xba'
# ( )
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp932')
#locale.getpreferredencoding(): cp932
#'\xba\xba'.decode('mbcs'): u'\uff7a\uff7a'
, , mbcs , , ’GBK’ , ’GBK’, ’MBCS’。
UTF-16 , ’UTF-16’ ’UTF-16-LE’ , ’UTF-16-LE’ 3 , ’UTF-16’ ’UTF-16-BE’ , 。 ,UTF-16 , 。