#はじめに
本記事は、Windows環境でパスの設定をする場合など「\」バックスラッシュを含んだ文字列を扱う際の、注意と対処法をまとめています。
(Macはパスの区切り文字が「/」スラッシュになっていますので、パスの設定の際はとくに気にしなくても大丈夫かと思います。)
#文字列に「\」バックスラッシュが含まれていると予期せぬ動作になる
例えば、下記のようにWindowsの環境でフォルダパスの指定をした際に、想定した文字列と異なる扱いになるときがあります。
dir_name = 'C:\testDir'
print(dir_name)
# 想定した文字列 > C:\testDir
# 実際に表示される文字列 > C: estDir
なぜこのようなことが起こるかというと、windowsのパスの区切り文字である**「\」バックスラッシュは、Pythonで「エスケープシーケンス」という処理に使われる**からです。
「エスケープシーケンス」がどういう処理かというと、例えば文字列の中で改行をしたいとき
txt = 'ここで改行→←改行'
# print(txt)で 以下のように表示させたい
# ここで改行→
# ←改行
改行を入れたいからといってエンターを押しても、コード上で改行されてしまいエラーになってしまいます。
txt = 'ここで改行→
←改行'
# SyntaxError: EOL while scanning string literal
そこで「改行」などの**特殊な文字を表すための方法が「エスケープシーケンス」**です。
改行を意味する文字は、バックスラッシュ'\
'と'n
'を組み合わせた'\n
'で表します。
txt = 'ここで改行→\n←改行'
print(txt)
# ↓表示される文字列
# ここで改行→
# ←改行
最初のパスの設定の例だと dir_name = 'C:\testDir'
の\t
部分が「TAB
」という文字に扱われ
Pythonで'C:[TAB]estDir'
と認識され、不自然にスペースの空いた文字列になっていたのです。
#対処法
そこで「\」をエスケープシーケンス用の「\」ではなく、そのまま「\」バックスラッシュという文字列として扱う方法があります。
##方法1:raw文字列
文字列の最初に「そのまま」という意味の「raw」の頭文字「r」をつけます。
raw文字列と言われ、エスケープシーケンスが行われず、そのままの文字列として扱われるようになります。
# rを付けると そのままの文字列として扱われ、エスケープされない
r'C:\testDir'
# ただし最後に「\」が含まれているものは対応できない
r'C:\testDir\'
# SyntaxError: EOL while scanning string literal
##方法2:「\」バックスラッシュをエスケープする
「\」も特殊な文字なので「これはバックスラッシュです」とエスケープシーケンスで表現することができます。
バックスラッシュを2つ「\\
」書くとバックスラッシュとして扱われます。
# バックスラッシュを2つ「\\」書いてバックスラッシュ自体をエスケープさせる
'C:\\testDir'
##方法3:「\」バックスラッシュを「/」スラッシュに書き換える
パスに対してならこの方法が一番いいと考えています。
Linux、Macのパスの区切り文字文字は「/」スラッシュになっているため、「/」に統一するよう意識すると、環境を変更したときの不具合を防止することができます。
Windowsも区切り文字「/」スラッシュで対応出来るため
「\」バックスラッシュを「/」スラッシュに書き換えて対処します。
# 「\」バックスラッシュを「/」スラッシュに書き換える
'C:/testDir'
###注意点
バックスラッシュをスラッシュに書き換える際の注意として
パスを取得する関数を利用した場合、パスの区切り文字は「\」バックスラッシュになります。
以下は、'C:\testDir'で実行しているとします。
import os
# カレントディレクトリの取得(作業中のフォルダ)
current_dir = os.getcwd()
print(current_dir)
# C:\testDir 「\」バックスラッシュで取得される
この取得したパスを利用して、以降のパスを自身で設定する場合、「/」「\」が混在しないように注意が必要です。
import os
# カレントディレクトリの取得
current_dir = os.getcwd()
# 画像用フォルダを設定 「/」で続きのパスを書く
image_dir = f'{current_dir}/image'
print(image_dir)
# C:\testDir/image 「\」「/」混在
pythonの関数では、混在していても動きはしますが、別のシステムにパスを渡すときや、パスを文字列操作するときにエラーになったりします。
例)SeleniumでChromeのダウンロードフォルダを設定するとき
そこで対処法として、パスを取得する際に「\」を「/」に置き換えてから、取得するようにします。
import os
# カレントディレクトリの取得のときに区切り文字を「/」に置き換え
current_dir = os.getcwd().replace(os.sep,'/')
print(current_dir)
# C:/testDir
#おわりに
ご覧いただきありがとうございました。
「\」バックスラッシュの対応方法はいろんな方法がありますが、現場や自分自身でルールを設けて統一して、不具合のない開発が出来るようにしていきましょう。
#参考
エスケープシーケンスを使用する
Pythonでエスケープシーケンスを無視(無効化)するraw文字列
セパレータの取得