Case1. 自分で作ったところで発生した場合
- 自分でopen関数などを書いた場合は対象のファイルがShift_JISであるかどうか確認します。
chardetで確認することができます
import chardet
with open(file, "rb") as f:
result = chardet.detect(f.read())
1-1. ファイルがShift_JISでないならShift_JISに変換します。
with codecs.open(file, "r", "utf-8") as file:
row_data = []
for row in file:
row_data.append(row)
with codecs.open(file, "w", "shift_jis") as file:
for row in row_data:
file.write(row)
1-2. ファイルをUTF-8で開きたい場合はencodingを付け足します。
f = open(file, encoding="utf-8")
そのうえでライブラリがopen関数などを読んでいる場合はシステムがどのエンコードを使っているかを確認します。
Case2. 依存しているライブラリから発生している場合
pythonで使っているデフォルトのエンコーディングがShift_JIS(CP932)になっており、基本のエンコーディングのUTF-8を読み込めなくなっている可能性があり増す。
以下のスクリプトを実行してみてください。
import os
import sys
import locale
print(os.environ.get("PYTHONIOENCODING"))
print(sys.getdefaultencoding())
print(sys.getfilesystemencoding())
print(sys.stdout.encoding)
print(locale.getpreferredencoding())
一つでも cp932 があるとそれが原因でファイルを読み込めない場合があります。
それぞれのケースで対処方法を見ていきます。
os.environ.get("PYTHONIOENCODING")でcp932が出た場合
sys.getdefaultencoding()でcp932が出た場合
以下で修正できます。
os.environ["PYTHONIOENCODING"] = "utf-8"
sys.getfilesystemencoding()でcp932が出た場合
あまりないと思いますが以下で直せます。
import sys
sys.getfilesystemencoding = lambda: 'UTF-8'
sys.stdout.encodingでcp932が出た場合
以下で修正できます。
sys.stdout.reconfigure(encoding='utf-8')
locale.getpreferredencoding()でcp932が出た場合
おそらく最もありえると思われるパターンです。
Windowsでのロケールを変更します。
以下が参考になります。
コントロールパネルより「地域」→「管理」から
「システムロケールの変更」を選んでください。
「ベータ:ワールドワイド言語サポートでUnicode UTF-8を使用」にチェックを入れます。
これで使われるロケールのエンコーディングがUTF-8になります。
別の対処法
Powershellで設定もできます。
New-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage' -Name 'ACP' -Value '65001' -PropertyType String -Force;
New-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage' -Name 'OEMCP' -Value '65001' -PropertyType String -Force;
New-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage' -Name 'MACCP' -Value '65001' -PropertyType String -Force;
戻すときは以下です。
New-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage' -Name 'ACP' -Value '932' -PropertyType String -Force;
New-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage' -Name 'OEMCP' -Value '932' -PropertyType String -Force;
New-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage' -Name 'MACCP' -Value '932' -PropertyType String -Force;
注釈:cp65001とは?
UTF-8の別名みたいです。
pythonでは以下のように出力されます。
import codecs
codecs.lookup('cp65001')
<codecs.CodecInfo object for encoding utf-8 at 0x1a62631cbe0>