前の記事で「python3のデフォルト文字コードがUTF-8だ」なんて書いたが、それはログインプロンプトからログインしたときだけであって、ログインせずに実行してしまうスクリプト(特にCGI)は、そうではない。このカラクリは環境変数「LANG」からpythonで使用するデフォルトの文字コードを取得して自動的に設定しているからである。
$ echo $LANG
ja_JP.UTF-8
CGIの実行ユーザになるであろう「nobody」「apache」「httpd」などはログインシェルは設定されていない(/bin/falseや/sbin/nologinなど)ので環境変数など設定できるわけもなくLANGはデフォルトの「C」(=ascii)であるので、pythonの文字コードもasciiとなる。
なので、CGIで日本語を含む文字列を出力しようとしたら例のごとく
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-14: ordinal not in range(128)
となってしまう。
解決方法
ソースの先頭のほうに以下を追記する。標準出力とエラー出力のエンコードをUTF-8に設定している
import io,sys
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
※importで呼び出す側およびにimportで呼び出される側両方のソースに上記コードを記載すると、だんまりエラーで異常終了するので注意!(エラーメッセージ出ず。例外処理も効かない。)
追記
ファイルに出力するときもpythonの文字コードがasciiになってしまっているが、上記方法では補正できない。
ファイル出力の文字コードを正しいものに修正するには、ファイルオープン時に文字コードを指定する。
fh=open("hoge.txt","a",encoding='utf-8')
“[python3]デフォルト文字コードの指定(CGI実行時)” への2件の返信