Почему элемент root, возвращаемый из os.walk () , показывает / в качестве разделителя каталогов, но os.sep (или os.path.sep ) показывает \ на Win10?
Я просто пытаюсь создать полный путь для набора файлов в папке следующим образом:
import os
base_folder = "c:/data/MA Maps"
for root, dirs, files in os.walk(base_folder):
for f in files:
if f.endswith(".png") and f.find("_N") != -1:
print(os.path.join(root, f))
print(os.path.sep)
Вот что я получаю как вывод:
c:/data/MA Maps\Map_of_Massachusetts_Nantucket_County.png
c:/data/MA Maps\Map_of_Massachusetts_Norfolk_County.png
\
Я понимаю, что некоторые из библиотечных функций python (например, open ()) будут работать со смешанными разделителями пути (по крайней мере, на Windows), но полагаться на этот взлом действительно нельзя доверять во всех библиотеках. Похоже, что элементы, возвращенные из os.walk () и os.path ( .sep или .join () ) должен давать согласованные результаты в зависимости от используемой операционной системы . Кто-нибудь может объяснить, почему происходит это несоответствие?
PS - я знаю, что существует более согласованная библиотека для работы с путями файлов (и множеством других манипуляций с файлами) , называемая pathlib , который был введен в python 3.4 и, похоже, все это исправляет. Если ваш код используется в версии 3.4 или выше, лучше ли использовать методы pathlib для решения этой проблемы? Но если ваш код предназначен для систем, использующих python до 3.4, как лучше всего решить эту проблему?
Вот хорошее базовое c объяснение pathlib : Python 3 Быстрый совет: простой способ справиться с путями к файлам на Windows, Ma c и Linux
Вот мой код и результат с использованием pathlib :
import os
from pathlib import Path
# All of this should work properly for any OS. I'm running Win10.
# You can even mix up the separators used (i.e."c:\data/MA Maps") and pathlib still
# returns the consistent result given below.
base_folder = "c:/data/MA Maps"
for root, dirs, files in os.walk(base_folder):
# This changes the root path provided to one using the current operating systems
# path separator (/ for Win10).
root_folder = Path(root)
for f in files:
if f.endswith(".png") and f.find("_N") != -1:
# The / operator, when used with a pathlib object, just concatenates the
# the path segments together using the current operating system path separator.
print(root_folder / f)
c:\data\MA Maps\Map_of_Massachusetts_Nantucket_County.png
c:\data\MA Maps\Map_of_Massachusetts_Norfolk_County.png
Это даже можно сделать более кратко, используя только pathlib и понимание списка (со всеми разделителями пути, правильно обработанными для используемой ОС):
from pathlib import Path
base_folder = "c:/data/MA Maps"
path = Path(base_folder)
files = [item for item in path.iterdir() if item.is_file() and
str(item).endswith(".png") and
(str(item).find("_N") != -1)]
for file in files:
print(file)
c:\data\MA Maps\Map_of_Massachusetts_Nantucket_County.png
c:\data\MA Maps\Map_of_Massachusetts_Norfolk_County.png
Это очень Pythoni c и, по крайней мере, я чувствую, что его легко читать и понимать. .iterdir () действительно мощный и делает работу с файлами и директориями достаточно простой и кросс-платформенной. Что ты думаешь?