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))
где я предполагаю, что полное отсутствие какой-либо вариации имени в регистре - это другой тип ошибки, и для этого используется исключение; и для всего пути (при условии отсутствия букв дисков или UNC, которые в любом случае не будут переводиться в Windows):
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
, как только он обнаружит ложное значение, так что это так же хорошо, как явный цикл, но быстрее и более кратким.