今日、後輩にプログラミングを教えていたときのことです。Python で中国語の文字をコマンドプロンプトに出力しようとしたところ、「UnicodeEncodeError: ‘cp950’ codec can’t encode character」というエラーが出てしまいました。いろいろな方法を試しても解決せず、最後はネットで調べてようやく原因がわかりました。

このエラーを見ると、経験のある開発者はすぐに文字列に特殊文字が含まれていると考え、ignore 引数を付けてみたりします。しかし、私の場合は効果がありませんでした。調べてみると、問題の原因は日本語の文字でした。Python 3 はデフォルトで Unicode 文字列を使うので、出力できないはずはないのですが……。まさか、あの悪名高い Big5 が原因なわけでもないですし……。

後で調べてわかったのですが、問題は Python 3 にあったわけではありませんでした。Python のプログラム内の文字列は Unicode で保存されています。出力先がターミナルの場合、Python はターミナルで使われているエンコーディングを確認し、Unicode 文字列をターミナルが対応しているエンコーディングに変換します。Linux で実行すると UTF-8 に変換されますが、Windows のコマンドプロンプトで Python を実行すると、いわゆる CP950 エンコーディングに変換されます。この変換の過程でエラーが発生していたのです。ただし、文字列をファイルに保存するなど他の処理をするのであれば、問題は起きません。

解決方法は2つあります。コマンドプロンプトのエンコーディングを UTF-8 に設定するか、Python で出力する前に文字列を CP950 にエンコードし、エラーになる文字を無視するかです。個人的には、コマンドプロンプトのエンコーディングを UTF-8 に設定することをおすすめします。コマンドプロンプトを開くたびに設定し直す必要はありますが、プログラム側で Windows 向けの調整をすると、プログラムをクロスプラットフォームで使うときにかえって問題が起きる可能性があるからです。

コマンドプロンプトで次のコマンドを入力すると、エンコーディングを UTF-8 に設定できます。ただし、コマンドプロンプトを開くたびに入力し直す必要があります:

chcp 65001

65001 は UTF-8 のコードページ番号です。

Python 側で対処したい場合は、次の例を参考にしてください:

s = "Hello 你好"
print(s.encode("utf8").decode("cp950", "ignore"))