ディレクトリのos.listdirは、大文字と小文字を保持するすべてのファイルシステム (Windows のファイルシステムを含む) で、リストしているディレクトリ内のファイル名の実際の大文字と小文字を返します。
したがって、パスの各レベルでこのチェックを行う必要があります。
def onelevelok(parent, thislevel):
for fn in os.listdir(parent):
if fn.lower() == thislevel.lower():
return fn == thislevel
raise ValueError('No %r in dir %r!' % (
thislevel, parent))
ここで、名前の大文字と小文字のバリエーションがまったくないことは別の種類のエラーであると想定しており、そのために例外を使用しています。そして、パス全体について (とにかく Windows に変換されないドライブ文字や UNC がないことを前提としています):
def allpathok(path):
levels = os.path.split(path)
if os.path.isabs(path):
top = ['/']
else:
top = ['.']
return all(onelevelok(p, t)
for p, t in zip(top+levels, levels))
たとえば、 が現在のディレクトリにあるfoo/bar
という意味ではなく、別の場所にあるという意味である場合は、これを調整する必要があるかもしれません。foo
または、もちろん、UNC またはドライブ文字が実際に必要な場合 (ただし、前述したように、それらを Linux に変換するのは簡単ではありません;-)。
実装上の注意: 私は、zip
圧縮するシーケンスの最短の長さを超えて「余分なエントリ」をドロップするという事実を利用しています。levels
そのため、最初の引数から「葉」(最後のエントリ) を明示的に切り取る必要はありzip
ません。all
可能な場合は短絡False
し、false 値を検出するとすぐに戻るため、明示的なループと同じくらい優れていますが、より高速で簡潔です。