読者です 読者をやめる 読者になる 読者になる

Pythonインタプリタと日本語

Python Mac

「みんなのPython」のマルチバイト文字列の解説の中に、

>>> l = [u"いち", u"に", u"さん"]
>>> l
[u'\u3044\u3061', u'\u306b', u'\u3055\u3093']

という例があったのですが、僕の環境(ソースからビイドしたPython2.4)では、

>>> l = [u"いち", u"に", u"さん"]
>>> l
[u'\xe3\x81\x84\xe3\x81\xa1', u'\xe3\x81\xab', u'\xe3\x81\x95\xe3\x82\x93']

というふうに、期待していた値とは異なる返ってくるので、疑問に思っていました。(u'\u3044\u3061'は有効な文字列ですが、u'\xe3\x81\x84\xe3\x81\xa1'はそうではありません。)


これは、ソースからビルドしたPythonだけの問題ではなく、python.orgで配布されているMac用のバイナリでも同様で、インタプリタモードではユニコード文字列を正しく解釈してくれません。


対処法は、分かってしまえば簡単で、configureする前に、

$ export LANG=ja_JP.UTF-8

のように、環境変数LANGを設定すればよいようです。
これで、インタプリタの入出力にUTF-8が使われるようになります。

>>> import sys
>>> sys.stdout.encoding
UTF-8
>>> sys.stdin.encoding
UTF-8


しかしながら、このようにエンコーディングをUTF-8に設定したPythonを使っても、evalやcompiler.parseなどの関数は、期待した通りの結果を返しません。

# -*- encoding: utf-8 -*-
u = eval("u'文字列'")
print u.encode('utf-8')

上のコードでは、入力も出力も、UTF-8に設定していますが、文字化けを起こしてしまいます。


これがなぜ問題かというと、KidやGenshiで、内部的にevalを使っているディレクティブが期待した通りに動作しないためです。

実際、Kidでは、py:attrsディレクティブの箇所が文字化けを起こします。

<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:py="http://purl.org/kid/ns#">
<body>
<h1 py:attrs="{'id':'greet', 'title':u'こんにちは世界'}">Hello World</h1>
</body>
</html>

Genshiにおいては、py:withを使った箇所が文字化けを起こします。

<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:py="http://genshi.edgewall.org/">
<body>
<h1 py:with="greeting=u'こんにちは世界'">${greeting}</h1>
</body>
</html>

対処法としては、テンプレートのpyディレクティブの中にユニコード文字列を使わない、などが考えられます。