バイト文字列とUnicode文字列

Pythonの文字列にはバイト文字列とUnicode文字列の二種類があります。

print "ぱいそん"  # バイト文字列 => ぱいそん
print u"ぱいそん" # Unicode文字列 => ぱいそん

バイト文字列

バイト文字列はいわゆる普通の文字列で、指定された文字エンコーディングに従って変換されたバイト列です。ですから、同じ文字列でも文字エンコーディングが違うと、出力される結果は同じでも、内部的には違うデータです。

# encoding=shift_jis
str = "ぱいそん"
print str   #=> ぱいそん
print [str] #=> ['\x82\xcf\x82\xa2\x82\xbb\x82\xf1']
# encoding=iso-2022-jp
str = "ぱいそん"
print str   #=> ぱいそん
print [str] #=> ['\x1b$B$Q$$$=$s\x1b(B']
# encoding=utf-8
str = "ぱいそん"
print str   #=> ぱいそん
print [str] #=> ['\xe3\x81\xb1\xe3\x81\x84\xe3\x81\x9d\xe3\x82\x93']


バイト文字列はバイト単位で処理されるため、日本語のように1文字が2バイト以上の文字列の場合、期待通りの結果を得られないことがあります。

>>> str = "ぱいそん"
>>> print len(str) # 文字列の長さを得る
8
>>> print str[1]   # 1番目の文字を取り出す

Unicode文字列

Unicode文字列はソースコードの文字エンコーディングが何であれ、全て同じデータです。

# encoding=shift_jis
str = u"ぱいそん"
print str   #=> ぱいそん
print [str] #=> [u'\u3071\u3044\u305d\u3093']
# encoding=iso-2022-jp
str = u"ぱいそん"
print str   #=> ぱいそん
print [str] #=> [u'\u3071\u3044\u305d\u3093']
# encoding=utf-8
str = u"ぱいそん"
print str   #=> ぱいそん
print [str] #=> [u'\u3071\u3044\u305d\u3093']


Unicode文字列は文字単位で処理されるので、日本語であっても期待通りの結果を得ることができます。日本語はUnicode文字列にしてから処理した方が安心です。

>>> str = u"ぱいそん"
>>> print len(str) # 文字列の長さを調べる
4
>>> print str[1]   # 1番目の文字を取り出す

バイト文字列 ⇔ Unicode文字列

バイト文字列からUnicode文字列を生成するにはdecode( )を使います。

>>> import sys
>>> str = "ぱいそん"
>>> str.decode(sys.stdin.encoding)

sys.stdin.encodingは標準入力の文字エンコーディングを返します。また、decode( )の引数を省略した場合は、sys.getdefaultencoding( )で得られる値が使用されますが、実際の文字エンコーディングと合っていないとエラーもしくは文字化けを起こすで、引数は省略しない方がいいです。


Unicode文字列をバイト文字列に変換するにはencode( )を使います。引数には変換したい文字エンコーディング名を渡します。

>>> import sys
>>> ustr = u"ぱいそん"
>>> ustr.encode(sys.stdout.encoding)
'\x82\xcf\x82\xa2\x82\xbb\x82\xf1'

文字コードの変換

文字コードの変換は、Unicode文字列を経由して行います。

>>> str = "ぱいそん" # cp932
>>> str
'\x82\xcf\x82\xa2\x82\xbb\x82\xf1'
>>> str.decode(sys.stdin.encoding).encode("utf-8")
'\xe3\x81\xb1\xe3\x81\x84\xe3\x81\x9d\xe3\x82\x93'