В этой статье будет рассмотрено руководство по использованию модуля «difflib» в Python. Модуль diffflib можно использовать для сравнения двух объектов Python определенных типов и просмотра сходств или различий между ними. Все примеры кода в этой статье протестированы с Python 3.9.5 в Ubuntu 21.04.
Модуль diffflib, как следует из названия, может использоваться для поиска различий или «различий» между содержимым файлов или других хешируемых объектов Python. Его также можно использовать для определения соотношения, показывающего степень сходства между двумя объектами. Использование модуля difflib и его функций лучше всего можно понять на примерах. Некоторые из них перечислены ниже.
В Python типы объектов, значение которых вряд ли изменится, или большинство неизменяемых типов объектов называются хешируемыми типами. Объекты типа Hashable имеют определенное фиксированное значение, присвоенное Python во время объявления, и эти значения не меняются в течение их срока службы. Все хешируемые объекты в Python имеют метод «__hash__». Взгляните на пример кода ниже:
number = 6 print (type(number)) print (number.__hash__()) word = "something" print (type(word)) print (word.__hash__()) dictionary = {"a" : 1, "b": 2} print (type(dictionary)) print (dictionary.__hash__())
После выполнения приведенного выше примера кода вы должны получить следующий результат:
6 2168059999105608551 Traceback (most recent call last): File "/main.py", line 13, in print (dictionary.__hash__()) TypeError: 'NoneType' object is not callable
Пример кода включает три типа Python: объект целочисленного типа, объект строкового типа и объект типа словаря. Выходные данные показывают, что при вызове метода «__hash__» объект целочисленного типа и объект строкового типа показывают определенное значение, в то время как объект типа словаря выдает ошибку, поскольку у него нет метода с именем «__hash__». Следовательно, целочисленный тип или строковый тип является хешируемым объектом в Python, а тип словаря – нет. Вы можете узнать больше о хэшируемых объектах здесь .
Вы можете сравнить два хешируемых типа или последовательности, используя класс «Differ», доступный в модуле diffflib. Взгляните на пример кода ниже.
from difflib import Differ line1 = "abcd" line2 = "cdef" d = Differ() difference = list(d.compare(line1, line2)) print (difference)
Первый оператор импортирует класс Differ из модуля difflib. Затем две переменные строкового типа определяются с некоторыми значениями. Затем создается новый экземпляр класса Differ как «d». Затем с помощью этого экземпляра вызывается метод «compare», чтобы найти разницу между строками «line1» и «line2». Эти строки предоставляются в качестве аргументов для метода сравнения. После выполнения приведенного выше примера кода вы должны получить следующий результат:
['- a', '- b', ' c', ' d', '+ e', '+ f']
Знаки тире или минус означают, что в строке 2 нет этих символов. Символы без знаков или пробелов в начале являются общими для обеих переменных. Символы со знаком плюс доступны только в строке «line2». Для лучшей читаемости вы можете использовать символ новой строки и метод «соединения» для построчного просмотра вывода:
from difflib import Differ line1 = "abcd" line2 = "cdef" d = Differ() difference = list(d.compare(line1, line2)) difference = '\n'.join(difference) print (difference)
После выполнения приведенного выше примера кода вы должны получить следующий результат:
- a - b c d + e + f
Вместо класса Differ вы также можете использовать класс «HtmlDiff» для создания цветного вывода в формате HTML.
from difflib import HtmlDiff line1 = "abcd" line2 = "cdef" d = HtmlDiff() difference = d.make_file(line1, line2) print (difference)
Пример кода такой же, как и выше, за исключением того, что экземпляр класса Differ был заменен экземпляром класса HtmlDiff, и вместо метода сравнения вы теперь вызываете метод make_file. После выполнения указанной выше команды вы получите вывод HTML в терминале. Вы можете экспортировать вывод в файл, используя символ «>» в bash, или вы можете использовать приведенный ниже пример кода для экспорта вывода в файл «diff.html» из самого Python.
from difflib import HtmlDiff line1 = "abcd" line2 = "cdef" d = HtmlDiff() difference = d.make_file(line1, line2) with open("diff.html", "w") as f: for line in difference.splitlines(): print (line, file=f)
Оператор «with open» в режиме «w» создает новый файл «diff.html» и сохраняет все содержимое переменной «разница» в файле diff.html. Когда вы открываете файл diff.html в браузере, вы должны получить подобный макет:
Если вы хотите получить данные сравнения из содержимого двух файлов с помощью метода Differ.compare(), вы можете использовать оператор «with open» и метод «readline» для чтения содержимого файлов. Пример ниже иллюстрирует это, где содержимое «file1.txt» и «file2.txt» читается с использованием операторов «with open». Операторы «с открытыми» используются для безопасного чтения данных из файлов.
from difflib import Differ with open ("file1.txt") as f: file1_lines = f.readlines() with open ("file2.txt") as f: file2_lines = f.readlines() d = Differ() difference = list(d.compare(file1_lines, file2_lines)) difference = '\n'.join(difference) print (difference)
Код довольно прост и почти такой же, как в примере, показанном выше. Предположим, что «file1.txt» содержит символы «a», «b», «c» и «d» каждый в новой строке, а «file2.txt» содержит символы «c», «d», «e» и Каждый символ «f» в новой строке, приведенный выше пример кода даст следующий результат:
- a - b c - d + d + e + f
Результат почти такой же, как и раньше, знак «-» представляет строки, отсутствующие во втором файле. Знак «+» показывает строки, присутствующие только во втором файле. Строки без знаков или с обоими знаками являются общими для обоих файлов.
Вы можете использовать класс «sequenceMatcher» из модуля difflib, чтобы найти коэффициент сходства между двумя объектами Python. Диапазон отношения подобия находится между 0 и 1, где значение 1 указывает на точное совпадение или максимальное сходство. Значение 0 указывает на полностью уникальные объекты. Взгляните на пример кода ниже:
from difflib import SequenceMatcher line1 = "abcd" line2 = "cdef" sm = SequenceMatcher(a=line1, b=line2) print (sm.ratio())
Экземпляр SequenceMatcher был создан с объектами для сравнения, предоставленными как аргументы «a» и «b». Затем в экземпляре вызывается метод «ratio», чтобы получить коэффициент подобия. После выполнения приведенного выше примера кода вы должны получить следующий результат:
0.5
Модуль diffflib в Python может использоваться различными способами для сравнения данных из разных хешируемых объектов или содержимого, считанного из файлов. Этот метод соотношения также полезен, если вы просто хотите получить процент сходства между двумя объектами.