Получение списка содержимого директории: os.listdir и его аналоги
Работа с функциями получения содержимого каталога в Python
Для получения списка имен файлов и подкаталогов в заданной директории в Python применяется функция os.listdir() из модуля os. Она возвращает список строк, содержащих имена всех элементов указанного пути. Эта функция является одной из базовых для системного администрирования, так как позволяет быстро получить перечень объектов файловой системы.
Наиболее эффективное решение
Стандартная запись вызова os.listdir() с явной обработкой ошибок и сортировкой результата обеспечивает надежное получение упорядоченного списка. Пример:
import os
def list_sorted(path='.'):
try:
items = os.listdir(path)
items.sort()
return items
except OSError as e:
print(f"Ошибка доступа или пути: {e}")
return []
print(list_sorted('/var/log'))
Python os environ (переменные окружения os.environ в python)
Сортировка обязательна, так как os.listdir() возвращает элементы в том порядке, в котором их отдает файловая система (часто недетерминированном). Обработка ошибок предотвращает аварийное завершение при отсутствии прав или несуществующем пути.
Типичные ошибки при использовании os.listdir
OSError/PermissionError: возникает, если у процесса нет прав на чтение каталога. Решение – проверка прав перед вызовом или перехват исключения.- Список содержит имена без полного пути:
os.listdir()возвращает только имена, поэтому для дальнейшего анализа (например, проверки, файл это или папка) требуется конкатенация с базовым путем. - Проблемы с кодировкой имен: в некоторых системах (особенно старых) имена файлов могут быть не в UTF-8. Рекомендуется указывать кодировку через параметр
encoding, доступный в Python 3.8+. - Скрытые файлы (начинающиеся с точки в Unix) включаются по умолчанию. Если нужно их игнорировать, требуется дополнительная фильтрация.
Как получить список только файлов (без каталогов)?
import os
def list_files(path):
try:
items = os.listdir(path)
files = []
for item in items:
full_path = os.path.join(path, item)
if os.path.isfile(full_path):
files.append(item)
return sorted(files)
except OSError as e:
print(f"Ошибка: {e}")
return []
Python os getenv (получение переменной окружения os.getenv в python)
Используется os.path.isfile() для проверки типа. Аналогично можно получить только подкаталоги с помощью os.path.isdir().
Как улучшить производительность при большом количестве файлов?
Вместо os.listdir() + многократных вызовов os.path.isdir() рекомендуется использование os.scandir(). Эта функция возвращает итератор объектов DirEntry, которые содержат предварительно полученную информацию о типе элемента без лишних системных вызовов:
import os
def list_files_scandir(path):
try:
with os.scandir(path) as it:
return sorted([entry.name for entry in it if entry.is_file()])
except OSError as e:
print(f"Ошибка: {e}")
return []
Python os listdir (список файлов в директории os.listdir в python)
os.scandir() быстрее, особенно на сетевых или медленных дисках.
Какие альтернативы существуют с использованием pathlib?
Модуль pathlib предоставляет объектно-ориентированный интерфейс. Метод Path.iterdir() возвращает генератор объектов Path:
from pathlib import Path
def list_files_pathlib(path):
p = Path(path)
try:
return sorted([entry.name for entry in p.iterdir() if entry.is_file()])
except PermissionError as e:
print(f"Нет доступа: {e}")
return []
Python os exists (проверка существования пути os.path.exists в python)
Преимущество – автоматическая конкатенация путей и богатый API.
Как рекурсивно обойти все поддиректории?
Для рекурсивного обхода применяется os.walk(), который генерирует кортежи (путь_каталога, список_подкаталогов, список_файлов):
import os
def print_all_files(root_path):
for dirpath, dirnames, filenames in os.walk(root_path):
for filename in filenames:
print(os.path.join(dirpath, filename))
Python os walk (обход директорий os.walk в python)
Это удобно для поиска файлов по маске или архивации. os.walk() использует os.listdir() внутри, но с рекурсивным спуском.
Как получить список файлов по шаблону (glob)?
Для поиска по маске удобен модуль glob:
import glob
# Все файлы .log в каталоге
log_files = glob.glob('/var/log/*.log')
print(log_files)
# Рекурсивный поиск всех .py файлов
py_files = glob.glob('/home/**/*.py', recursive=True)
Python имя компьютера (имя компьютера в python)
Этот вариант не требует ручной фильтрации и поддерживает шаблоны оболочки.
Проблемы при работе с русскими именами файлов
В Windows файловые системы NTFS используют кодировку UTF-16, в Linux – UTF-8 или другие. При передаче не-ASCII имен через os.listdir() могут возникать ошибки, если системная локаль не совпадает. Рекомендуется в Python 3.8+ использовать параметр encoding='utf-8' или errors='surrogateescape':
os.listdir('.', encoding='utf-8')Но в большинстве случаев современные ОС возвращают имена в Unicode, и проблемы редки.
Расширенные примеры использования os.listdir() и связанных функций.
Пример 1. Получение списка с полными путями и фильтрация по расширению
import os
def list_files_by_ext(path, extension):
result = []
try:
for name in os.listdir(path):
if name.endswith(extension):
full = os.path.join(path, name)
if os.path.isfile(full):
result.append(full)
except OSError as e:
print(f"Ошибка: {e}")
return result
print(list_files_by_ext('/tmp', '.txt'))
['/tmp/notes.txt', '/tmp/data.txt']
Пример 2. Кроссплатформенное получение списка только каталогов с игнорированием скрытых
import os
def list_dirs_except_hidden(path):
items = []
try:
for name in os.listdir(path):
if not name.startswith('.'):
full = os.path.join(path, name)
if os.path.isdir(full):
items.append(name)
except OSError as e:
print(e)
return items
print(list_dirs_except_hidden('/usr'))
['bin', 'lib', 'share', ...]
Пример 3. Использование scandir для получения метаданных
import os
def show_file_info(path):
with os.scandir(path) as it:
for entry in it:
if entry.is_file():
print(f"{entry.name}: {entry.stat().st_size} bytes")
show_file_info('/etc')
passwd: 1024 bytes hosts: 320 bytes ...
Пример 4. Рекурсивное удаление файлов по условию с os.walk
import os
def remove_tmp_files(root):
for dirpath, _, filenames in os.walk(root):
for f in filenames:
if f.endswith('.tmp'):
full_path = os.path.join(dirpath, f)
try:
os.remove(full_path)
print(f"Удалён {full_path}")
except OSError as e:
print(f"Не удалось удалить {full_path}: {e}")
remove_tmp_files('/tmp/testdir')
Удалён /tmp/testdir/old.tmp Удалён /tmp/testdir/sub/file.tmp
Пример 5. Сортировка по времени изменения
import os
def list_sorted_by_mtime(path):
try:
items = os.listdir(path)
items.sort(key=lambda name: os.path.getmtime(os.path.join(path, name)), reverse=True)
return items
except OSError as e:
print(e)
return []
print(list_sorted_by_mtime('/var/log')[:5])
['syslog', 'kern.log', 'auth.log', ...]
Пример 6. Обработка ошибок с использованием suppress из contextlib
import os
from contextlib import suppress
def safe_listdir(path):
with suppress(OSError):
return sorted(os.listdir(path))
return []
print(safe_listdir('/proc')) # под root может быть недоступно
Этот подход скрывает все исключения уровня ОС, что может быть полезно в скриптах, где не требуется явная реакция на ошибки.