概要
Python2.7での文字列の扱い方の基本や注意すべき点をまとめる。
普段はPython3を使っているがPython2.7で書かれたプログラムの保守をすることがあり、いろいろ戸惑ったのでその時のメモ。ご存知の通り、Python2からPython3への移行の際に文字列に関する大きな変更が入り、後方互換性が失われている。
この記事内の情報は、特に明示しない限りPython2についてである。
前提知識
符号化文字集合と文字符号化方式(主にUnicodeとUTF-8)の違いについて、だいたい理解していること。
これを読めば、だいたいOKかも。 Unicode入門
プログラムの方針
下記は、Pythonのドキュメントからの引用。Unicodeを扱うプログラムを書くための助言として書かれている。
ソフトウェア内部の動作には Unicode 文字列のみを利用し、出力時に特定のエンコーディングに変換する。
https://docs.python.jp/2.7/howto/unicode.html#tips-for-writing-unicode-aware-programs
この助言にしたがい、Unicode文字列の使い方、特定のエンコーディングへの変換について見ていく。
Unicode文字列
Unicode 文字列は Python の組み込み型の一つ unicode 型のインスタンスとして表現されます。
https://docs.python.jp/2.7/howto/unicode.html#python-2-x-s-unicode-support
Unicode文字列は、文字列の先頭にu
をつけると作成可能。
>>> u"a"
u'a'
>>> type(u"a")
<type 'unicode'>
Unicodeのコードポイントを指定することもできる。\u
+ 4桁の16進数で表現する。
>>> u"\u0061" == u"a"
True
この方法を利用すると、「こんにちは」は、u'\u3053\u3093\u306b\u3061\u306f'
となる。
ソースコード内のUnicode文字列
「こんにちは」は、u'\u3053\u3093\u306b\u3061\u306f'
ではなく、「こんにちは」と書きたい。しかし、何も考えずに、これをやろうとするエラーになる。(対話的インタープリタではエラーにならないが、それはまた別の話)
$ cat foo.py
print u'こんにちは'
$ python2.7 foo.py
File "foo.py", line 1
SyntaxError: Non-ASCII character '\xe3' in file foo.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
ソースファイルにエンコーディングを宣言すれば良い。
$ cat foo_with_encofing.py
# -*- coding: utf-8 -*-
print u'こんにちは'
$ python2.7 foo_with_encofing.py
こんにちは
Python3ではデフォルトで"UTF-8"として認識されるので、coding
の指定は不要になった。
特定のエンコーディングへの変換
Unicode文字列を特定のエンコーディング(例えばUTF-8)へ変換する。
encode()を使えばよい。
>>> u"a".encode('utf-8')
'a'
>>> type(u"a".encode('utf-8'))
<type 'str'>
エンコードを行うとstr型のオブジェクトが作成されるが、これはバイト列を表す点に注意が必要。(Python3のstr型とは異なる)
特定のエンコーディングからUnicodeリテラルへの変換
今度は反対に、特定のエンコーディングから(例えばUTF-8)からUnicode文字列へ変換する。
decode()を使えばよい。
>>> "あ"
'\xe3\x81\x82'
>>> type("あ")
<type 'str'>
>>> type("あ".decode("utf-8"))
<type 'unicode'>
変換時のエラーに対応する
encode()およびdecode()には、エラー時の挙動をキーワード引数で指定することができる。
https://docs.python.org/ja/2.7/library/codecs.html
https://docs.python.org/ja/2.7/library/codecs.html#codec-base-classes