Help us understand the problem. What is going on with this article?

Windows 上の Python で UTF-8 をデフォルトにする

TL;DR: UTF-8をデフォルトで使いたい人は環境変数に PYTHONUTF8=1 を設定しよう

Python は文字列が unicode なので、あちこちで「適切」なエンコーディングを選択する必要があります。残念ながら後方互換性やWindows固有の事情によりまだ ANSI Code Page (日本語なら cp932) がデフォルトで使われる場面があります。

ざっと Python と外の世界との入出力をあげてみます。

  • テキストファイルを読み書きする時のデフォルトのエンコーディング = ACP
  • 標準入出力のエンコーディング
    • 標準入出力がコンソールのとき = UTF-16 で WriteConsoleW 等を呼ぶ
    • 標準入出力がコンソールでない時 = ACP
  • 子プロセスとのPIPE = ACP

最近 chcp 65001 を使って UTF-8 を使う方法が広まっているように思います。これはコンソールのエンコーディングを指定する (SetConsoleCP(), SetConsoleOutputCP()) ものなので、標準出力がリダイレクトされた場合には関係ありません。

# Power Shell 6
PS C:¥> python3 -c "print('おはよう')" > ps.txt

# cmd.exe
C:¥> chcp 65001
C:¥> python3 -c "print('おはよう')" > cmd.txt

同じコマンドに見えますが、 Power Shell 6 で出力した ps.txt は UTF-8 で書かれていて、 cmd.exe で出力した cmd.txt は cp932 で出力されました。 Power Shell は python3 の標準出力を一旦受け取り、 cp932 から UTF-8 に変換してリダイレクト先に書き込んでいるからです。

さて、 Python 3.7 からは最終兵器である UTF-8 mode (PEP 540) があります。このモードは Python を起動する時にコマンドラインオプションで -X utf8 を追加するか環境変数で PYTHONUTF8=1 を設定しておくと有効になります。このモードではエンコーディングは次のようになります。

  • テキストファイルを読み書きする時のデフォルトのエンコーディング = UTF-8
  • 標準入出力のエンコーディング
    • 標準入出力がコンソールのとき = UTF-16 で WriteConsoleW 等を呼ぶ
    • 標準入出力がコンソールでない時 = UTF-8
  • 子プロセスとのPIPE = UTF-8

これで一貫して UTF-8 を使うことができます。

この状態では子プロセスとのパイプもデフォルトではUTF-8になってしまうので、cp932を使うコマンドを利用する&パイプをテキストモードで開くときにはエンコーディングに "mbcs" か "cp932" を指定する必要があります。

cp932 のままのコンソールを使う場合も、コンソール自体への入出力は WriteConsoleW が使われるので文字化けしないはずです。テキストファイルのエンコーディングがUTF-8に切り替わるのも多くの人にとってはメリットでしょう。 (type コマンドでそのファイルを表示すると文字化けしますが)

一方 PowerShell を使う場合、 python3.exe が標準出力に UTF-8 を書いているよと簡単に伝える手段が不明です。(この記事 を見つけたのですが、コマンドを実行するたびにこれをするのは...)

Python を Windows 上で使ってなるべく UTF-8 を使いたい人は次のような装備を揃えると良いでしょう。

  • デフォルトで UTF-8 を利用するテキストエディタ (VS Code, Atom, Windows 10 1903 以降のメモ帳)
  • cp65001 を利用するように設定した cmd.exe (あるいは勝手に cp932 -> UTF-8 変換しないシェル)
  • 環境変数 PYTHONUTF8=1 を設定した Python 3.7 以降
klab
モバイルオンラインゲーム、その他スマートフォン関連サービス、及びサーバーインフラ開発・運用
http://www.klab.com/jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした