Вопрос-Ответ

Extract file name from path, no matter what the os/path format

Извлечение имени файла из path, независимо от формата os / path

Какую библиотеку 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
Переведено автоматически
Ответ 1

Есть функция, которая возвращает именно то, что вы хотите

import os
print(os.path.basename(your_path))

ПРЕДУПРЕЖДЕНИЕ: Когда os.path.basename() используется в системе POSIX для получения базового имени из пути в стиле Windows (например, "C:\\my\\file.txt"), будет возвращен полный путь.

Приведенный ниже пример из интерактивной оболочки python, работающей на хосте Linux:

Python 3.8.2 (default, Mar 13 2020, 10:14:16)
[GCC 9.3.0] on Linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> filepath = "C:\\my\\path\\to\\file.txt" # A Windows style file path.
>>> os.path.basename(filepath)
'C:\\my\\path\\to\\file.txt'
Ответ 2

Использование os.path.split или os.path.basename, как предлагают другие, будет работать не во всех случаях: если вы запускаете скрипт в Linux и пытаетесь обработать путь в классическом стиле Windows, это приведет к сбою.

Пути Windows могут использовать либо обратную, либо прямую косую черту в качестве разделителя пути. Следовательно, ntpath модуль (который эквивалентен os.path (при запуске в Windows) будет работать для всех(1) путей на всех платформах.

import ntpath
ntpath.basename("a/b/c")

Конечно, если файл заканчивается косой чертой, базовое имя будет пустым, поэтому создайте свою собственную функцию для обработки этого:

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 папки. Поэтому, когда в path используются как прямые, так и обратные косые черты, вам нужно знать соответствующую платформу, чтобы иметь возможность правильно ее интерпретировать. На практике обычно можно с уверенностью предположить, что это путь Windows, поскольку обратная косая черта редко используется в именах файлов Linux, но помните об этом при написании кода, чтобы не создавать случайных дыр в безопасности.

Ответ 3

os.path.split - это функция, которую вы ищете

head, tail = os.path.split("/tmp/d/a.dat")

>>> print(tail)
a.dat
>>> print(head)
/tmp/d
Ответ 4

В python 3.4 или более поздней версии с pathlib.Path:

>>> from pathlib import Path    
>>> Path("/tmp/d/a.dat").name
'a.dat'

Свойство .name предоставит полное имя последнего дочернего элемента в path, независимо от того, является ли это файлом или папкой.

python