Mac/Linuxしか触ってなかった人生から一転、毎日Windowsを使うお仕事に就きました。
最近はちょっとしたツールをよく作るのですが、Windowsで1番悩まされてるのは、Windowsのパスが"\"で連結されていることです。
コマンドプロンプトとcygwinでどちらも動かすようなコードを書く場合です。
例えばこんな感じのコードを書くと
import os path = "C:\documents\nori\tama" for d in os.listdir(path): print os.path.join(path, d)
もちろんこうなるわけで。
WindowsError: [Error 123] ファイル名、ディレクトリ名、またはボリューム ラベルの 構文が間違っています。: 'C:\\documents\nori\tama/*.*'
「"\"ってエスケープされるじゃん!なんでWindowsのパスは\でつなぐの?! /でいいじゃん!」
仕方がないので、こんなかんじに\\でパスを設定しておくようにしていました。
path = "C:\documents\nori\tama"
path = "C:\\documents\\nori\\tama"
でも\を\\に変えるのもいい加減に面倒なので、まじめに解決方法を考えましょう。
解決法1 raw文字列を使う
path = r"C:\documents\nori\tama"
raw文字列("の前にrをつける)とエスケープシーケンスが無効になるので、\\を重ねずにすみます。
ただし末尾に'\'はこられないので注意です。
参考:
Python におけるバックスラッシュ (\) の扱いと、row stirng と正規表現における注意点 | すぐに忘れる脳みそのためのメモ
解決法2 そもそもWindowsのパスは/で繋げる
path = "C:/documents/nori/tama"
別に \ じゃなくて / でも大丈夫なのです。
そもそもWindowsのパスはなぜバックスラッシュ?
なんで "\"なのか調べてみました。
本の虫: なぜDOSのパスはバックスラッシュなのか
簡単に言うと、
- /が既にオプション指定文字だったから
- 某社の陰謀
というような感じっぽい。
とりあえず "/"でつないでも大丈夫なことがわかったところで次の問題。
/ と \(¥)が混ざって表示される問題
さっきの raw文字列や / を使うことで、パスを指定することには成功したわけですが、次の問題です。
import os path = "C:/documents/nori/tama" for d in os.listdir(path): print os.path.join(path, d)
これを実行するとコマンドプロンプトで実行すると、こんな感じになります。
C:/documents/nori/tama\dir1 C:/documents/nori/tama\dir2 C:/documents/nori/tama\windowspath.py
/ と \ が混ざってて気持ち悪い! \(^◇^)/
動くけど!動くけど・・・。
raw文字列を使うと今度はシェルで実行した時に混ざるのです。
解決法3 os.sepでreplace
いろいろためしてみた結果、これがos.sepをでreplaceするのが1番よい気がしました。
os.sep
パス名を要素に分割するためにオペレーティングシステムで利用されている文字です。例えば POSIX では '/' で、Windowsでは '\\' です。
参考: 15.1. os — 雑多なオペレーティングシステムインタフェース — Python 2.7.14 ドキュメント
/で指定をしておいて、os.sepでreplaceします。
import os path = "C:/documents/nori/tama".replace('/', os.sep) for d in os.listdir(path): print os.path.join(path, d)
これで、コマンドプロンプトで実行すれば
C:\documents\nori\tama\dir1 C:\documents\nori\tama\dir2 C:\documents\nori\tama\windowspath.py
cygwin等で実行すれば
C:/documents/nori/tama/dir1 C:/documents/nori/tama/dir2 C:/documents/nori/tama/windowspath.py
どっちで実行しても良い感じになりました。やったー!
さいごに
他にもっとよい方法があれば教えて下さい!
Windowsのパスと表現するかdosのパスと表現するか迷ったのだけど、Windowsのパスとかいてしまった。 dosの、といったほうが正確な気がしてる。よくわからない。