Python unicode型とstring型について

僕はPythonを使って一年も経たない入門者ですが、その短い期間で一番頻繁に悩んだ問題が、unicode型とstring型の変換エラーだと思います。

Traceback (most recent call last):
  File "/home/ryota/test.py", line 14, in <module>
    print a
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-4: ordinal not in range(128)

などというエラーをよく見かけるわけです。


コンピュータそのものが専門ではないため文字コードなど詳しくはないですが、他の用途で使っているうちにエラーの回避方法は分かったのでまとめておきます。


基本的に、
・端末に表示させたい、ファイル書き込みを行いたい…string型
・文字列処理を行うときにPythonが扱う型…Unicode

stringとunicode型の扱いですが、宣言と代入の段階では、

a="あいうえお"
print type(a) #<type 'str'>
print a #あいうえお
a=u"あいうえお"
print type(a) #<type 'unicode'>
print a #普通はERROR(後述)

で区別されます。


string型とunicode型の変換は、

#coding:utf-8
a="あいうえお"
print type(a)
print type(unicode(a,'utf-8'))
print type(a.decode('utf-8'))
a=u"あいうえお"
print type(a)
print type(a.encode('utf-8'))


そして、要注意なのがPythonのstring型とunicode型の自動変換です。
僕はこの機能を知らなかったため、string型とunicode型の違いが理解できないことがありました。

#coding:utf-8
a="あいうえお"
print "%s" % a
b=u"あいうえお"
print "%s" % b #OK
print "%s,%s" % (a,b) #ERROR

環境によると思いますが、4行目は表示できます。
しかし5行目はほぼ確実にエラーになります。
これは、unicode型をstring型に自動変換しているためだと分かりますが、文字フォーマットにstring型とunicode型を混在させるとエラーになりました。

#coding:utf-8
a=u"あいうえお"
b=u"あいうえお"
c=u"あいうえお"
d="あいうえお"
print "%s,%s,%s,%s" % (a,b,c,d.decode('utf-8'))

全てunicode型に統一するならば、表示させることができるようです。
が、これも環境よりきなようで、端末ならば受理されますが、sublime textの端末ではエラーのようです。。

Pythonの自動変換機能は場合によっては非常に分かりにくくするので気をつけるようにしています。