Извлечение имени файла из пути независимо от формата ОС/пути
Какую библиотеку Python я могу использовать для извлечения имен файлов из путей, независимо от операционной системы или формата пути?
Например, я хотел бы, чтобы все следующие пути возвращали мне c
:
a/b/c/
a/b/c
\a\b\c
\a\b\c\
a\b\c
a/b/../../a/b/c/
a/b/../../a/b/c
5 ответ(ов)
Использование методов os.path.split
или os.path.basename
, как предлагают другие, не всегда будет работать: если вы запустите скрипт на Linux и попытаетесь обработать классический путь в формате Windows, это приведет к ошибке.
Пути Windows могут использовать как обратные слэши (\
), так и прямые слэши (/
) в качестве разделителей. Поэтому модуль ntpath
(который эквивалентен os.path
, когда скрипт выполняется на Windows) будет корректно обрабатывать все пути на всех платформах.
Вот пример:
import ntpath
ntpath.basename("a/b/c")
Тем не менее, если файл заканчивается на слэш, basename
вернется пустым, поэтому предлагаю создать собственную функцию для обработки этого случая:
def path_leaf(path):
head, tail = ntpath.split(path)
return tail or ntpath.basename(head)
Чтобы проверить работу функции, выполните следующий код:
>>> paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c',
... 'a/b/../../a/b/c/', 'a/b/../../a/b/c']
>>> [path_leaf(path) for path in paths]
['c', 'c', 'c', 'c', 'c', 'c', 'c']
^(1) Есть одно замечание: имена файлов в Linux могут содержать обратные слэши. Поэтому на Linux путь r'a/b\c'
всегда будет ссылаться на файл b\c
в папке a
, тогда как на Windows он всегда будет ссылаться на файл c
в подпапке b
в папке a
. Таким образом, когда в пути используются и прямые, и обратные слэши, вам необходимо знать, на какой платформе вы работаете, чтобы правильно его интерпретировать. На практике обычно безопасно предположить, что это путь в формате Windows, поскольку обратные слэши редко используются в именах файлов на Linux, но имейте это в виду при написании кода, чтобы не создавать случайные уязвимости.
В Python 3.4 и новее, используя pathlib.Path
, вы можете получить имя конечного элемента пути с помощью свойства .name
. Вот пример:
>>> from pathlib import Path
>>> Path("/tmp/d/a.dat").name
'a.dat'
Свойство .name
вернет полное имя последнего элемента в пути, независимо от того, является ли это файлом или папкой.
Вы можете использовать модуль os
для получения имени файла и его пути к директории. Вот пример кода, который делает именно это:
import os
file_location = '/srv/volume1/data/eds/eds_report.csv'
file_name = os.path.basename(file_location) # Получаем имя файла: 'eds_report.csv'
location = os.path.dirname(file_location) # Получаем путь к директории: '/srv/volume1/data/eds'
В этом коде os.path.basename()
возвращает имя файла из полного пути, а os.path.dirname()
возвращает путь к каталогу, в котором этот файл находится.
Мой личный фаворит — это такой код:
filename = fullname.split(os.sep)[-1]
Этот способ позволяет извлечь имя файла из полного пути fullname
, разбивая строку по разделителю, специфичному для операционной системы, и беря последний элемент. Это удобный и лаконичный метод для получения имени файла из полного пути.
Если вы хотите автоматически получить имя файла, вы можете сделать это следующим образом:
import glob
import os
for f in glob.glob('/ваш/путь/*'):
print(os.path.split(f)[-1])
В этом коде используется модуль glob
для поиска файлов в указанной директории. Функция glob.glob('/ваш/путь/*')
возвращает список всех файлов и папок в указанной директории. Затем с помощью os.path.split(f)[-1]
мы извлекаем только имя файла из полного пути.
Как создать каталог и все отсутствующие родительские каталоги?
Как получить имя файла без расширения из пути в Python?
Функциональность mkdir -p в Python
Как получить абсолютный путь к файлу в Python
Как использовать для поиска файлов рекурсивно?