Сообщить об ошибке.

Модуль filecmp в Python, сравнение файлов и каталогов

Сравнение файлов и каталогов в файловой системе

Модуль filecmp определяет функции для сравнения файлов и каталогов с различными дополнительными компромиссами времени и корректности.

Для сравнения двух файлов в файловой системе используйте функцию filecmp.cmp(). Аргумент shallow сообщает filecmp.cmp(), следует ли просматривать содержимое файла в дополнение к его метаданным. По умолчанию выполняется поверхностное сравнение с использованием информации, доступной из os.stat(). Если результаты статистики совпадают, файлы считаются одинаковыми.

>>> import filecmp
# сравнивает только статистику файлов
>>> filecmp.cmp('path/to/file1', 'path/to/file2')
# дополнительно сравнивает содержимое файла
>>> filecmp.cmp('path/to/file1', 'path/to/file2', shallow=False)

Для получения различий в тексте двух файлов смотрите также модуль difflib.

Чтобы сравнить набор файлов в двух каталогах без рекурсии, используйте функцию filecmp.cmpfiles(). Аргументами являются имена каталогов и список файлов для проверки в двух местах. Переданный список общих файлов должен содержать только имена файлов, каталоги всегда приводят к несоответствию, так же файлы должны присутствовать в обоих каталогах.

import filecmp, os

# преобразовываем списки файлов 
# каталогов dir1 и dir2 в множества 
file_dir1 = set(os.listdir('path/to/dir1'))
file_dir1 = set(os.listdir('path/to/dir2'))

# находим пересечение множеств, тем
# самым получаем общие имена
common = list(file_dir1 & file_dir2)

# Теперь проверяем список common
# на файлы, чтобы не попался каталог
common_files = [
    file_name
    for file_name in common
    if os.path.isfile(os.path.join('path/to/dir1', file_name))
]

# Сравниваем общие файлы каталогов
match, mismatch, errors = filecmp.cmpfiles(
    'path/to/dir1',
    'path/to/dir2',
    common_files,
)

Для рекурсивного сравнения больших деревьев каталогов или для более полного анализа используйте класс filecmp.dircmp(). В простейшем случае метод экземпляра класса dircmp.report() печатает отчет сравнения двух каталогов. Вывод представляет собой простой текстовый отчет, показывающий результаты только содержимого заданных каталогов без рекурсии. Для получения более подробной информации и рекурсивного сравнения используйте метод dircmp.report_full_closure().

Помимо создания печатных отчетов, класс filecmp.dircmp() рассчитывает списки файлов, которые можно использовать непосредственно в программах. Каждый из атрибутов экземпляра класса вычисляется только по запросу, поэтому создание объекта dircmp не требует дополнительных затрат для неиспользуемых данных. Входные данные могут быть отфильтрованы путем передачи списка имен, которые следует игнорировать.

Вот упрощенный пример использования атрибута dircmp.subdirs для рекурсивного поиска в двух каталогах и отображения общих файлов:

import filecmp

def print_diff_files(dcmp):
    for name in dcmp.diff_files:
        print(f`diff_file {name} found in {dcmp.left} and {dcmp.right}`)
    for sub_dcmp in dcmp.subdirs.values():
        print_diff_files(sub_dcmp)

dcmp = dircmp('path/to/dir1', 'path/to/dir2') 
print_diff_files(dcmp)