Python: работа с суффиксами файлов (расширениями)
Работа с расширениями файлов в Python
Как получить расширение файла наиболее современным и надёжным способом?
Основной рекомендуемый подход - использование модуля pathlib, который входит в стандартную библиотеку Python начиная с версии 3.4. Метод .suffix возвращает расширение файла вместе с точкой, а .suffixes возвращает список всех расширений для файлов с несколькими точками.
from pathlib import Path
file_path = Path('document.tar.gz')
extension = file_path.suffix # '.gz'
extensions = file_path.suffixes # ['.tar', '.gz']
print(extension)
print(extensions)
ввод программ на python (ввод данных в программе python)
.gz ['.tar', '.gz']
Python file io (ввод-вывод файлов в python)
Типичная ошибка:
Если файл не имеет расширения, .suffix вернёт пустую строку ''. Не путайте это с наличием точки в имени (например, 'file.' вернёт '.'). Для проверки существования расширения используйте условие if file_path.suffix:.
Как узнать расширение файла с помощью os.path.splitext?
Классический метод из модуля os.path. Функция os.path.splitext разделяет путь на кортеж (имя_без_расширения, расширение). Этот способ работает во всех версиях Python.
import os
filename = 'data.csv'
root, ext = os.path.splitext(filename)
print(f'Имя: {root}, Расширение: {ext}')
Python temp files (временные файлы в python)
Имя: data, Расширение: .csv
Python index files (индексация файлов в python)
Важно:
os.path.splitext корректно обрабатывает точки только в конце имени. Для путей с несколькими точками (например, 'archive.tar.gz') он выделит только последнее расширение '.gz'. Если нужны все расширения, используйте Path.suffixes из pathlib.
Как извлечь расширение файла с помощью строковых методов?
Простейший, но ненадёжный вариант - найти последнюю точку в строке имени файла через str.rfind('.') и взять подстроку. Не рекомендуется для production, так как не учитывает особенности путей (например, точки в каталогах).
filename = 'example.py'
if '.' in filename:
ext = filename[filename.rfind('.'):]
else:
ext = ''
print(repr(ext))
File python class (класс для работы с файлами в python)
'.py'
Python file utf 8 (кодировка utf-8 для файлов в python)
Проблема:
Если имя файла начинается с точки (скрытые файлы в Unix, например '.bashrc'), rfind('.') может дать неверный результат: вся строка будет считаться расширением. Лучше использовать os.path.splitext или pathlib, которые корректно обрабатывают такие случаи.
Как проверить, имеет ли файл определённое расширение, с помощью регулярных выражений?
Иногда требуется не просто получить расширение, а проверить его соответствие шаблону (например, допускается несколько вариантов). Модуль re позволяет гибко задавать условия.
import re
filename = 'photo.jpeg'
pattern = r'\.(jpg|jpeg|png|gif)$'
if re.search(pattern, filename, re.IGNORECASE):
print('Это изображение')
else:
print('Другой формат')
Python config files (конфигурационные файлы в python)
Это изображение
Python copy file (копирование файла в python)
Предостережение:
Регулярное выражение может быть избыточным для простой проверки. Для проверки одного расширения достаточно сравнить строку после .suffix или os.path.splitext. Регулярки оправданы при сложных масках (например, любое расширение из заданного набора).
Как заменить расширение файла на другое?
Часто нужно переименовать файл, изменив его расширение. Лучший способ - использовать Path.with_suffix из pathlib.
from pathlib import Path
old_path = Path('report.txt')
new_path = old_path.with_suffix('.pdf')
print(f'Новый путь: {new_path}')
# Фактическое переименование:
old_path.rename(new_path)
Python log file (логирование в файл в python)
Новый путь: report.pdf
Осторожно:
with_suffix заменяет только последнее расширение. Для файла 'backup.tar.gz' вызов with_suffix('.zip') даст 'backup.tar.zip', а не 'backup.zip'. Для полной замены всех расширений используйте Path.stem (имя без всех суффиксов).
Расширенные примеры работы с расширениями файлов
# 1. Массовое получение расширений всех файлов в директории
from pathlib import Path
directory = Path('.')
for file in directory.iterdir():
if file.is_file():
print(f'{file.name}: {file.suffix}')
# Результат (пример):
# readme.md: .md
# script.py: .py
# data.csv: .csv
readme.md: .md script.py: .py data.csv: .csv
# 2. Фильтрация файлов по расширению с использованием списковых включений
from pathlib import Path
directory = Path('/home/user/documents')
python_files = [f for f in directory.iterdir() if f.suffix == '.py']
print(f'Найдено {len(python_files)} Python файлов')
# Результат:
# Найдено 3 Python файлов
Найдено 3 Python файлов
# 3. Получение расширения из полного пути (в том числе с сетевыми путями)
import os
full_path = '/var/log/system.log.1'
ext = os.path.splitext(full_path)[1]
print(f'Расширение: {ext}')
# Результат:
# Расширение: .1
Расширение: .1
# 4. Безопасное переименование всех файлов с одним расширением в другое
from pathlib import Path
source_dir = Path('./images')
target_ext = '.png'
source_ext = '.jpg'
for file in source_dir.glob(f'*{source_ext}'):
new_file = file.with_suffix(target_ext)
if not new_file.exists():
file.rename(new_file)
print(f'Переименован: {file.name} -> {new_file.name}')
else:
print(f'Пропущен (уже существует): {new_file.name}')
# Результат (пример):
# Переименован: cat.jpg -> cat.png
# Пропущен (уже существует): dog.png
Переименован: cat.jpg -> cat.png Пропущен (уже существует): dog.png
# 5. Работа с расширениями без точки (например, для сравнения)
from pathlib import Path
filename = 'script.py'
ext_with_dot = Path(filename).suffix # '.py'
ext_without_dot = ext_with_dot[1:] if ext_with_dot else ''
print(f'Расширение без точки: {ext_without_dot}')
# Результат:
# Расширение без точки: py
Расширение без точки: py
# 6. Использование регулярных выражений для извлечения всех расширений из имени
import re
filename = 'my.file.name.tar.gz'
extensions = re.findall(r'\.([a-zA-Z0-9]+)', filename)
print(f'Все расширения: {extensions}')
# Результат:
# Все расширения: ['file', 'name', 'tar', 'gz']
Все расширения: ['file', 'name', 'tar', 'gz']
# 7. Определение типа файла по расширению (mime - упрощённо)
ext_to_type = {
'.txt': 'text/plain',
'.html': 'text/html',
'.jpg': 'image/jpeg',
'.png': 'image/png',
'.pdf': 'application/pdf'
}
file_ext = '.jpg'
mime = ext_to_type.get(file_ext, 'application/octet-stream')
print(f'MIME-тип для {file_ext}: {mime}')
# Результат:
# MIME-тип для .jpg: image/jpeg
MIME-тип для .jpg: image/jpeg
# 8. Обработка ошибок при работе с расширениями (файл без расширения, скрытые файлы)
from pathlib import Path
filenames = ['hidden_file', '.bashrc', 'file.test.docx', 'image.png']
for name in filenames:
p = Path(name)
suffix = p.suffix
stem = p.stem # имя без последнего расширения, но для .bashrc stem будет пустым
print(f'{name:20} -> suffix: {suffix!r:6}, stem: {stem!r}')
# Результат:
# hidden_file -> suffix: '' , stem: 'hidden_file'
# .bashrc -> suffix: '' , stem: '.bashrc' (внимание!)
# file.test.docx -> suffix: '.docx', stem: 'file.test'
# image.png -> suffix: '.png' , stem: 'image'
hidden_file -> suffix: '' , stem: 'hidden_file' .bashrc -> suffix: '' , stem: '.bashrc' file.test.docx -> suffix: '.docx', stem: 'file.test' image.png -> suffix: '.png' , stem: 'image'