2009-03-07
2chのPythonアンチスレが勉強になる件
なんかアンチスレなのに色々勉強になる。
http://pc11.2ch.net/test/read.cgi/tech/1203557046/
pythonのユニコード出力の際のエラーについてよくまとまっている208さんの記述を無断引用する
標準出力がリダイレクトされていない場合、Python の print 文は 与えられた Unicode 文字列を自動的に cp932 等の実行環境固有のエンコーディングで エンコードして印字するようになっている。これは Python インタプリタを 対話的に利用するときには便利な仕組みだ。「実行環境固有のエンコーディング」が 具体的に何であるかは sys.stdout.encoding を見れば分かる。 一方、標準出力がファイル等にリダイレクトされている場合、 どのエンコーディングで文字列をエンコードすべきかを決めるのは難しい問題だ。 cp932 がいいかもしれないし用途によっては utf-8 や iso-8859-1 の方がいいかも知れない。 つまり、Python の立場からは標準出力をリダイレクトする場合のエンコーディングを これと決めることができない。このことは、標準出力をリダイレクトしているときには sys.stdout.encoding が None になることから分かる。 この場合、print 文は sys.stdout.encoding の代わりに sys.getdefaultencoding() が返す エンコーディングでエンコードして出力する。このエンコーディングは Python の出荷時の 設定では ascii になっているので、日本語等を含む Unicode 文字列を print しようとすると 実行時エラーになる。 結局のところ、標準出力をファイルにリダイレクトできるようにプログラムを書くには sys.stdout.encoding による自動エンコードに頼らないようにしなければいけないということだ。 個人的には、Unicode 文字列をファイルなり標準出力なりに書き出すときは 明示的にエンコードするように心がけるべきだと考えている。暗黙の自動エンコードに 頼るとロクなことがない。 じゃあ具体的にどうすればいいのかという話だけど、お勧めは次の方法だ。 まず次のように標準出力を適当なエンコーダで包む。 import codecs Writer = codecs.getwriter(sys.getfilesystemencoding()) stdout = Writer(sys.stdout) その上で print 文をすべて次のように書く。 print >>stdout, '"total","%s",%d' % (root, dirsize[root]) この例ではリダイレクトしているか否かに関わらず sys.getfilesystemencoding() の返す エンコーディングでエンコードするようにしている。このエンコーディングは、俺の知る限り 標準出力がリダイレクトされていない場合の sys.stdout.encoding と一致している。 sys.getfilesystemencoding() を使う代わりに、例えば cp932 に決めうちしちゃうとか、 コマンドライン引数で出力エンコーディングを指定するようにするといった方法も考えられる。 標準出力リダイレクト時のエンコーディングをどうするかは用途に強く依存する問題なので こればかりはプログラムを書く人(つまり197さん)が決めるしかない。
トラックバック - http://d.hatena.ne.jp/lolloo-htn/20090307/1236409021
リンク元
- 23 http://www.google.co.jp/url?sa=t&rct=j&q=python 2ch&source=web&cd=4&sqi=2&ved=0CDAQFjAD&url=http://d.hatena.ne.jp/lolloo-htn/20090307/1236409021&ei=XBukTo3iEuugmQWBzfyeCQ&usg=AFQjCNGbR8sWne6Ln1emPzE8j85I8k69sA
- 18 http://www.google.co.jp/search?hl=ja&client=firefox-a&rls=org.mozilla:ja:official&hs=xFn&q=画像+ダウンロード+pixiv&btnG=検索&lr=lang_ja
- 15 https://www.google.co.jp/
- 14 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=11&ved=0CCoQFjAAOAo&url=http://d.hatena.ne.jp/lolloo-htn/20090307/1236409021&ei=gAJiT9H8H-6UiAeMnJTZBQ&usg=AFQjCNGbR8sWne6Ln1emPzE8j85I8k69sA&sig2=MkTRmbMuMJzTJrgm180zhg
- 14 http://www.google.co.jp/url?sa=t&rct=j&q=2ch python&source=web&cd=4&ved=0CDoQFjAD&url=http://d.hatena.ne.jp/lolloo-htn/20090307/1236409021&ei=LV-kTpuuOqOkmQXNksCfCQ&usg=AFQjCNGbR8sWne6Ln1emPzE8j85I8k69sA&cad=rja
- 13 http://reader.livedoor.com/reader/
- 12 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=4&ved=0CEEQFjAD&url=http://d.hatena.ne.jp/lolloo-htn/20090307/1236409021&ei=vxFnT_qgFof6mAWg1smqCA&usg=AFQjCNGbR8sWne6Ln1emPzE8j85I8k69sA&sig2=gicA_F_mSPrSqMMUIgve7g
- 10 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=0CC8QFjAB&url=http://d.hatena.ne.jp/lolloo-htn/20090307/1236409021&ei=VzxpT42iHaLvmAWXlKCjCQ&usg=AFQjCNGbR8sWne6Ln1emPzE8j85I8k69sA
- 8 http://d.hatena.ne.jp/johzan/
- 8 http://d.hatena.ne.jp/johzan/searchdiary?word=*[Python]