PythonのUTF-8化
Python 2からPython 3への移行
Python 2では、ソースコードのデフォルトエンコーディングがASCIIで、バイト文字列とユニコード文字列の暗黙的な型変換が可能でした。しかし、これは多くの問題を引き起こしていました。Python 3への移行では、バイト列と文字列が明確に区別され、デフォルトエンコーディングがUTF-8になりました。この変更は大きな互換性の問題を引き起こしましたが、長期的には有益だったと評価されています。
Windows環境でのUTF-8対応
Python 3.6では、WindowsでのUTF-8対応が大幅に改善されました。コンソールI/OがUTF-8化され、ファイルパスの扱いも改善されました。これにより、Windows環境でも他のプラットフォームと同様にUTF-8を扱えるようになりました。
コンテナ時代への対応
Python 3.7では、コンテナ環境でのUTF-8対応が強化されました。ロケールがCの場合にUTF-8モードが自動的に有効になり、必要に応じてUTF-8ロケールに矯正されるようになりました。これにより、コンテナ環境でのPythonの使いやすさが大幅に向上しました。
完全UTF-8化への挑戦
2019年以降、Pythonの完全UTF-8化に向けた取り組みが加速しました。Windows May 2019 Updateでメモ帳のデフォルトがUTF-8になったことも追い風となり、PythonでもUTF-8をデフォルトにする議論が活発化しました。
未来のPython:UTF-8がデフォルトに
最終的に、Python 3.15(2026年リリース予定)からUTF-8モードがデフォルトで有効になることが決定しました。これにより、エンコーディングに関する多くの問題が解消されることが期待されています。
各エンコーディング
- デフォルトエンコーディング
- sys.getdefaultencoding()で取得
- str.encode(), bytes.decode()で使われる
- すでにUTF-8
- ファイルシステムエンコーディング
- sys.getfilesystemencoding()で取得
- Unixではロケールエンコーディング
- windowsはUTF-8
- テキストエンコーディング
- Io.TextIOWrapperがデフォルトで使うエンコーディング
- open(), stdout, subprocess.PIPEなど
- ロケールエンコーディング
- ロケールエンコーディング
- locale.getencoding()で取得できる
- Unixでは、locale(LC_CTYPE)で取得できるもの
- WinではANSI codee page(GetACP()) -> 日本語ではcp932
現在の推奨コード
open はencodingを指定しないとローカルエンコーディングされるので、日本語windowsでは、cp932が使われてしまう。また、古いjsonでもバイナリモードであれば、読み込めるので、これが推奨となります。
with open('config.json', 'b') as f:
cfg = json.load(f)
まとめ
PYTHONUTF8=1環境変数を設定してUTF-8モードを積極的に使用することを推奨しています。また、エンコーディングの問題を早期に発見するために、PYTHONWARNDEFAULTENCODING=1を設定することも提案されました。
Pythonでは文字エンコーディング対応が着実に進化してきました。UTF-8のデフォルト化は、国際化されたアプリケーション開発をより簡単にし、エンコーディングに関連するバグを減らすことが期待されます。開発者として、これらの変更に注目し、積極的にUTF-8モードを活用していくことが重要だと感じました。