"Unicode Error 'unicodeescape' codec can't decode bytes..." when writing Windows file paths の原因と直し方【Dockerで検証済み】
"Unicode Error 'unicodeescape' codec can't decode bytes..." when writing Windows… の原因と解決方法。検証済みの解決コマンド付きで、現象→原因→解決→確認の順に最短で直せます。
発生したエラー
"Unicode Error 'unicodeescape' codec can't decode bytes..." when writing Windows file paths結論:まずこれで直ります
このエラーはWindowsファイルパスをPythonの通常の文字列リテラルにそのまま書いたときに発生します。下の解決コマンドを順に実行すれば直ります。
cat > /tmp/fix_unicode_path.py << 'EOF'
import os
from pathlib import Path
# 方法1: raw文字列を使う(推奨)
path1 = r'C:\Users\username\Documents\file.txt'
print('方法1 (raw string):', path1)
# 方法2: バックスラッシュを二重エスケープする
path2 = 'C:\\Users\\username\\Documents\\file.txt'
print('方法2 (escaped backslash):', path2)
# 方法3: フォワードスラッシュを使う
path3 = 'C:/Users/username/Documents/file.txt'
print('方法3 (forward slash):', path3)
# 方法4: os.path.join を使う
path4 = os.path.join('C:\\', 'Users', 'username', 'Documents', 'file.txt')
print('方法4 (os.path.join):', path4)
# 方法5: pathlib を使う
path5 = Path('C:/') / 'Users' / 'username' / 'Documents' / 'file.txt'
print('方法5 (pathlib):', path5)
EOF
python3 /tmp/fix_unicode_path.py現象どんなエラーか
次の操作を行うと(検証環境: python:3.11)、上記のエラーが発生します。まずは下の再現コマンドで、同じ状況を再現できることを確認してください。
検証環境:python:3.11
python3 << 'PYEOF'
path = 'C:\Users\username\Documents\file.txt'
print(path)
PYEOF原因なぜ起きるのか
このエラーはWindowsファイルパスをPythonの通常の文字列リテラルにそのまま書いたときに発生します。Pythonはバックスラッシュをエスケープシーケンスの開始文字として解釈するため、例えば `'C:\Users'` の `\U` はUnicodeエスケープ(`\UXXXXXXXX` 形式)として解釈しようとしますが、後続の文字が正しいUnicodeコードポイントの形式でないためSyntaxErrorになります。根本的な解決策は主に3つです。①文字列の先頭に `r` を付けてraw文字列リテラルにする(`r'C:\Users\...'`)— バックスラッシュがエスケープ文字として解釈されなくなり、最もシンプルな方法です。②バックスラッシュを `\\` と二重に書いてエスケープする。③Windowsでもフォワードスラッシュ `C:/Users/...` は有効なので代わりに使う。またクロスプラットフォームのコードでは `os.path.join()` や `pathlib.Path` でパスを組み立てる方法がより堅牢です。前回の verify スクリプトでは、Pythonの `-c` オプションに渡す文字列にシェルレベルでのエスケープ処理が絡んで同じエラーが再発していました。今回はスクリプトをヒアドキュメントでファイルに書き出してから実行することで、シェルとPythonのエスケープ処理が混在する問題を回避しています。
解決解決手順
cat > /tmp/fix_unicode_path.py << 'EOF'
import os
from pathlib import Path
# 方法1: raw文字列を使う(推奨)
path1 = r'C:\Users\username\Documents\file.txt'
print('方法1 (raw string):', path1)
# 方法2: バックスラッシュを二重エスケープする
path2 = 'C:\\Users\\username\\Documents\\file.txt'
print('方法2 (escaped backslash):', path2)
# 方法3: フォワードスラッシュを使う
path3 = 'C:/Users/username/Documents/file.txt'
print('方法3 (forward slash):', path3)
# 方法4: os.path.join を使う
path4 = os.path.join('C:\\', 'Users', 'username', 'Documents', 'file.txt')
print('方法4 (os.path.join):', path4)
# 方法5: pathlib を使う
path5 = Path('C:/') / 'Users' / 'username' / 'Documents' / 'file.txt'
print('方法5 (pathlib):', path5)
EOF
python3 /tmp/fix_unicode_path.py確認直ったか確認する
cat > /tmp/verify_unicode_path.py << 'EOF'
import sys
import os
from pathlib import Path
# 方法1: raw文字列
path1 = r'C:\Users\username\Documents\file.txt'
assert 'Users' in path1, 'raw string failed'
assert 'username' in path1, 'raw string failed'
# 方法2: 二重エスケープ
path2 = 'C:\\Users\\username\\Documents\\file.txt'
assert 'Users' in path2, 'escaped backslash failed'
assert 'username' in path2, 'escaped backslash failed'
# 方法3: フォワードスラッシュ
path3 = 'C:/Users/username/Documents/file.txt'
assert 'Users' in path3, 'forward slash failed'
# 方法4: os.path.join
path4 = os.path.join('C:\\', 'Users', 'username', 'Documents', 'file.txt')
assert 'Users' in path4, 'os.path.join failed'
# 方法5: pathlib
path5 = Path('C:/') / 'Users' / 'username' / 'Documents' / 'file.txt'
assert 'Users' in str(path5), 'pathlib failed'
print('All path methods work correctly')
sys.exit(0)
EOF
python3 /tmp/verify_unicode_path.py動画で見る
この記事の解決手順は実環境で検証しています
山田 英紀(社内SE 5年以上・13業種以上の業務システムを開発/運用)が、 掲載コマンドを検証環境で実行し、再現〜解決〜確認まで通ることを確認しています。