2008年9月8日月曜日

Python の日本語の扱いで混乱中… (+_+) - 文字列フォーマット操作を使えばいいの?

print 文でオブジェクトの情報を表示

例えば、「人」を表す Person クラスがあるとする。 print 文に Person オブジェクトを渡し、オブジェクトの情報が表示されるように Person クラスに __str__() メソッドを実装した。

__str__(self)

組み込み関数 str() および print 文によって呼び出され、 オブジェクトを表す ``非公式の'' 文字列を計算します。

(3.3.1 基本的なカスタマイズ より)

Person クラスは、「名前」「年齢」からなる。このオブジェクトを print 文に渡したら「名前 : 年齢」という書式で表示されるようにしたい。

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __str__(self):
        return self.name + " : " + str(self.age)

しかし、以下を実行すると、

p = Person(u"太郎", 20)
print p

次のようなエラーが表示された。 (@_@;)

exceptions.UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

ただし、Person オブジェクトの名前を “Tarou” のように英字にすればエラーは表示されない。 UnicodeEncodeError について調べてみると、いろいろと対処方法が書かれていて、今一よくわからず。 (+_+)  脳みそオーバーフロー。 パタッ(o_ _)o~†

 

ユニコード文字列の扱い

もっとシンプルな状況で考えてみる。

hoge = u"ほげ"
print hoge
print str(hoge)

str() 関数を適用した時点で、同じく UnicodeEncodeError  。(+_+)  "”hoge”  のように英字ならば問題なし。ただし、次のようにすれば日本語でも表示された。

print str(hoge.encode('shift_jis'))

しかし、わざわざ encode() するのは面倒だなぁ… ^^;

 

文字列フォーマット操作

以前に print 文で変数をフォーマットして出力する方法を試した。(cf. Python で文字列中の変数をフォーマットして置き換える ) 試しに次のように書いて実行。

print "%s" % hoge

ん?普通に「ほげ」と出力された。(@_@)

2.3.6.2 文字列フォーマット操作 の変換型の表によると、

s 文字列 (python オブジェクトを str() で変換します)。

str() を呼んでいるはずなのになぜ UnicodeEncodeError が投げられないのだろうか?

「注釈」を見たら、

オブジェクトや与えられた書式が unicode 文字列の場合、変換後の文字列も unicode になります。

うーん、これが理由なのかな?

 

オブジェクトに対して文字列フォーマット操作

そこで、最初の Person オブジェクトも同じように文字列フォーマット操作で出力させてみると、

print "%s" % p

結果、

太郎 : 20

お!日本語がちゃんと表示された。 ^^

それにしても、日本語の扱いってどうするのが一番いいのだろう (?_?)

 

環境

  • OS : Windows XP SP3
  • Python : Python 2.5.2
  • ファイルのエンコーディング : UTF-8
  • IDE : Python Scripter