54
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-06-13

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 以降
54
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
54
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?