ユニコード文字列と8ビット文字列

ユニコード文字列と8ビット文字列

Python の文字列にはユニコード文字列と8ビット文字列がある。8ビット文字列というのが正式な言い方かどうかはわからないけど「みんなのPython」の中ではそう呼んでいる。
で、どう違うかというと、言ってみればユニコード文字列はPythonの内部表現で、8ビット文字列はその他のエンコードを持った文字列といってよさそう。

ユニコード文字列のリテラルには、頭に u をつける。

>>> s = u'abc'
>>> type(s)
<type 'unicode'>

上にあるように、ユニコード文字列の型は unicode になる。これに対して普通の文字列、つまり8ビット文字列の型は str だ。

>>> s2 = 'abc'
>>> type(s2)
<type 'str'>

スクリプトエンコーディング

ASCII文字だけを使うときは気にすることは無いけど、日本語を使うときにはスクリプトのエンコーディングにも気をつけなきゃいけない。といっても、Pythonの場合は UTF-8 にしておくのはほとんどデフォルトのようだ。
スクリプトのエンコーディングは、1行目か2行目に次のように書く。

# coding: utf-8

もちろん、スクリプトファイルをUTF-8で保存するのを忘れずに。

日本語の出力

Windowsで日本語を出力するときには、ユニコード文字列をShift-JISに変換してやる。
エンコードの変換には、文字列の encode 関数が使える。

# coding: utf-8

s = u'こんにちは'

print s.encode('sjis')

実行結果:

^o^ > python konnichiwa.py
こんにちは

実はわざわざsjisにエンコードしなくてもちゃんと出力される。

# coding: utf-8

s = u'こんにちは'

print s

実行結果:

^o^ > python konnichiwa2.py
こんにちは

どうも暗黙のうちにコンソールに合わせてエンコードしてくれているみたいだ。だけど、これだとファイルにリダイレクトするとうまくいかない。

^o^ > python konnichiwa2.py > konnichiwa.txt
Traceback (most recent call last):
  File "konnichiwa2.py", line 5, in 
    print s
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-4: ordin
al not in range(128)

‘ascii’ codec がエンコードできないといっている。標準出力のときにはうまくいくのにリダイレクトすると何でだめなのか、謎。

日本語を入力

コマンドラインから日本語を入力することを考える。
スクリプトの外部から来た文字列はすべて8ビット文字列だ。だから、ユニコード文字列に変換してやる必要がある。変換には文字列の decode 関数が使える。

# coding: utf-8

import sys

name = sys.argv[1].decode('sjis')

s = u'こんにちは' + name

print s.encode('sjis')

実行結果:

^o^ > python konnichiwa3.py アンディ
こんにちはアンディ

Pythonで使えるエンコード名

最後に書いておこう。

エンコードPythonのエンコード名
シフトJISshift-jis shift_jis sjis
ISO-2022-JPiso-2022-jp
EUC-JPeuc-jp
UTF-8utf-8