ASPN : Python Cookbook : print statement: battle with UnicodeEncodeError

Python Workshop the Edgeの懇親会で少し話に出たけど、UnicodeEncodeError、UnicodeDecodeErrorの動きが微妙に分からない。同じ標準出力に吐くのでも、ファイルにリダイレクトしたらエラーになるとか。

でこれはエラーが出る場合は16進表記で書き出すというもの。

調べたこと。

  • reload(sys)
  • sys.setdefaultencoding(encoding)
  • sys.stdout=codecs.getwriter(encoding)(sys.stdout)

reload(sys)

reload関数はモジュールを再読み込み、再パースする。この行をコメントアウトしてみると

Traceback (most recent call last):
File "console.py", line 47, in ?
sys.setdefaultencoding('cp1251') # set default encoding for source
AttributeError: 'module' object has no attribute 'setdefaultencoding'

となる。
setdefaultencodingはデフォルトでは無効らしい。

sys.setdefaultencoding(encoding)

デフォルト文字エンコーディングを指定する。
site.pyに書くこともできるが一部asciiを前提としたライブラリが残っているので推奨されない、とクックブックにも書いてあった。

sys.stdout=codecs.getwriter(encoding)(sys.stdout)

標準出力をラップする。
クックブックの

sys.stdout = codecs.lookup(encoding)[-1](sys.stdout)

と同じ動作なのだろうか。どちらでも動いた。

getwriterのほうが表現がきれいだな。

(追記)同じだった。

>>> import codecs
>>> codecs.lookup("utf-8")[-1]

>>> codecs.getwriter("utf-8")

lookupはCodecInfoというオブジェクトを返してる。

その他

for i in list(msg):

for i in msg:

でいいのではないか。