Как получить название файла из пути с помощью Python
Получение имени файла из пути в Python: обзор методов
Как получить имя файла из строки пути с использованием современного подхода?
Наиболее эффективное и рекомендуемое решение - модуль pathlib, входящий в стандартную библиотеку Python. Он предоставляет объектно-ориентированный интерфейс для работы с путями и корректно обрабатывает разделители на разных ОС.
from pathlib import Path
path_str = "/home/user/documents/report.pdf"
filename = Path(path_str).name
print(filename) # report.pdfPython file filename (получение имени файла из пути)
Метод .name возвращает последний компонент пути - имя файла с расширением. Если путь заканчивается на слеш (например, /home/user/), результатом будет пустая строка. Это важно учитывать при обработке путей к директориям.
Проблема: Путь, оканчивающийся на разделитель, даёт пустое имя. Решение: предварительно удалить конечный слеш с помощью .rstrip('/\\') или проверять, является ли путь файлом через .is_file().
path = Path("/home/user/documents/")
name = path.name
print(repr(name)) # ''
# Корректное получение имени последней папки
name = path.parent.name if path.name == '' else path.name
print(name) # documents
Как получить имя файла без использования pathlib (только os.path)?
Классический способ - функция os.path.basename. Она принимает строку и возвращает имя независимо от типа разделителя, но только для системного пути.
import os
path_str = "C:\\Users\\Alice\\photo.jpg"
filename = os.path.basename(path_str)
print(filename) # photo.jpg
Важно: На Windows следует использовать сырые строки (r"...") или удваивать обратные слеши, чтобы избежать экранирования.
Ошибка: Если передать путь с косой чертой (Unix-style) на Windows, basename всё равно корректно выделит имя, так как os.path адаптируется к текущей платформе. Однако при работе с путями из других систем может потребоваться предварительная нормализация: os.path.normpath(path).replace('\\', '/').
Как применить функцию split для разделения пути на директорию и имя?
Функция os.path.split возвращает кортеж (head, tail), где tail - имя файла.
head, tail = os.path.split("/var/log/syslog")
print(tail) # syslog
Если путь оканчивается слешом, tail будет пустым. Для полного контроля можно использовать .rsplit() с учётом платформы.
Проблема: os.path.split не различает файл и папку - он просто делит строку по последнему разделителю. Для проверки типа используйте os.path.isfile() или Path.is_file().
Как извлечь имя файла без расширения или только расширение?
Метод Path.stem возвращает имя без суффикса, Path.suffix - расширение (с точкой).
p = Path("data/archive.tar.gz")
print(p.stem) # archive.tar
print(p.suffix) # .gz
# Для получения только последнего расширения:
print(p.suffixes) # ['.tar', '.gz']
Аналог из os.path - os.path.splitext, но он отделяет только одно расширение.
filename, ext = os.path.splitext("data.tar.gz")
print(filename, ext) # data.tar .gz
Как обработать путь с обратными слешами на Windows без pathlib?
Если необходимо использовать только встроенные функции, можно нормализовать и заменить разделители:
path = r"C:\Users\Admin\file.txt"
# Замена обратных слешей на прямые
normalized = path.replace('\\', '/')
filename = os.path.basename(normalized)
print(filename) # file.txt
Однако os.path.basename сам корректно работает с обратными слешами на Windows, поэтому такая замена излишня, если код выполняется на целевой ОС. Для кроссплатформенных сценариев лучше использовать pathlib.
Как извлечь имя файла из объекта Path, который уже создан?
Объект Path имеет свойство .name, а также .stem и .suffix.
p = Path("/some/dir/myfile.py")
print(p.name) # myfile.py
print(p.stem) # myfile
print(p.suffix) # .py
Дополнительно можно получить относительный путь относительно другого каталога: p.relative_to(Path("/some")) вернёт dir/myfile.py.
Расширенные примеры получения имени файла из пути
1. Извлечение имени из сетевого пути (UNC)
UNC-пути на Windows начинаются с двойного обратного слеша:
from pathlib import Path
unc_path = "//server/share/folder/file.txt"
p = Path(unc_path)
print(p.name) # file.txt
# Для обратных слешей:
unc_path_win = "\\\\server\\share\\folder\\file.txt"
p2 = Path(unc_path_win)
print(p2.name) # file.txt
file.txt file.txt
2. Обработка путей с точками в имени файла
Имя может содержать несколько точек, и важно понимать, как отделяется расширение:
from pathlib import Path
p = Path("my.project.v1.0.tar.gz")
print("Name:", p.name)
print("Stem:", p.stem)
print("Suffix:", p.suffix)
print("Suffixes:", p.suffixes)
# Только последнее расширение через os.path:
import os
print(os.path.splitext(p.name)) # ('my.project.v1.0.tar', '.gz')
Name: my.project.v1.0.tar.gz
Stem: my.project.v1.0.tar
Suffix: .gz
Suffixes: ['.v1', '.0', '.tar', '.gz']
('my.project.v1.0.tar', '.gz')
3. Извлечение имени из пути, представленного как bytes
Иногда пути приходят в виде байтов (например, из системных вызовов). Модуль pathlib поддерживает bytes:
from pathlib import Path
path_bytes = b"/home/user/file.txt"
p = Path(path_bytes)
print(p.name) # file.txt
print(type(p.name)) # str, не bytes
# Для обратного преобразования:
print(p.name.encode()) # b'file.txt'
file.txtb'file.txt'
4. Получение имени файла из URL (файловый протокол)
Если путь задан в виде URL file://, стандартные функции не подойдут. Используйте urllib.parse:
from urllib.parse import urlparse, unquote
from pathlib import Path
url = "file:///home/user/file%20name.txt"
parsed = urlparse(url)
path = unquote(parsed.path) # /home/user/file name.txt
filename = Path(path).name
print(filename) # file name.txt
file name.txt
5. Использование регулярных выражений для извлечения имени из произвольной строки
Если формат пути нестандартный, можно применить регулярное выражение, которое захватывает последний компонент до точки или разделителя:
import re
paths = ["/path/to/file.txt", "C:\\folder\\file.exe", "data.json"]
pattern = r"[^\\/]+$" # один или более символов, не являющихся \ или /
for p in paths:
match = re.search(pattern, p)
print(f"{p!r} -> {match.group()}")
'/path/to/file.txt' -> file.txt 'C:\\folder\\file.exe' -> file.exe 'data.json' -> data.json
6. Пакетная обработка списка путей с записью в словарь
Сценарий: имеется список путей, нужно создать словарь, где ключ - имя файла, значение - полный путь.
from pathlib import Path
paths = [
"/var/log/syslog",
"/etc/hostname",
"/home/user/.bashrc"
]
result = {}
for path_str in paths:
p = Path(path_str)
result[p.name] = str(p)
print(result)
# Осторожно: если встречаются одинаковые имена, последнее перезапишет предыдущее.
# Для сохранения всех используйте словарь со списками.
{'syslog': '/var/log/syslog', 'hostname': '/etc/hostname', '.bashrc': '/home/user/.bashrc'}
7. Извлечение имени из пути с символической ссылкой
Если путь является символической ссылкой, Path.name вернёт имя самой ссылки, а не целевого файла. Для получения имени целевого файла используйте resolve():
from pathlib import Path
link = Path("/tmp/mylink")
# Предположим, что link указывает на /etc/passwd
print(link.name) # mylink
print(link.resolve().name) # passwd
mylink passwd