Почему корневой элемент, возвращаемый из 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()< /strong>) должны давать согласованные результаты в зависимости от используемой операционной системы. Кто-нибудь может объяснить, почему происходит это несоответствие?
P.S. - Я знаю, что существует более согласованная библиотека для работы с путями к файлам (и множества других операций с файлами), называемая pathlib, которая была введена в Python 3.4 и, кажется, исправляет все это. Если ваш код используется в версии 3.4 или выше, лучше ли использовать методы pathlib для решения этой проблемы? Но если ваш код предназначен для систем, использующих Python до версии 3.4, как лучше всего решить эту проблему?
Вот хорошее базовое объяснение pathlib: Краткий совет по Python 3: простой способ работать с путями к файлам в Windows, Mac и 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
Это очень Pythonic, и, по крайней мере, я чувствую, что это довольно легко читать и понимать. .itertir() действительно мощная функция, которая делает работу с файлами и каталогами достаточно простой и кросс-платформенной. Что вы думаете?
\
для авторских прав. Но он поддерживал совместимость с POSIX, позволяя также использовать/
в качестве разделителя пути. Вы использовали жестко заданный начальный каталог с/
, но каталог проходит по добавленным подкаталогам со стандартным для ОС\
. Вы можете нормализовать, получить абсолютный путь к вашему жестко запрограммированному стартовому каталогу. - person Joop Eggen   schedule 16.04.2020