日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python diff函数_使用Python创建你自己的diff工具

發(fā)布時間:2024/9/19 python 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python diff函数_使用Python创建你自己的diff工具 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

為什么我需要自己的diff工具?

我經(jīng)常使用git跟蹤我的編碼項(xiàng)目、文章、業(yè)務(wù)工作等等。git的一個美妙之處在于,你可以通過簡單地使用其內(nèi)置的diff功能來輕松地比較你的工作的不同狀態(tài)。要使用這個功能,你只需要滿足兩個約束:首先,你需要一個git存儲庫,其次,該文件需要由git存儲庫進(jìn)行跟蹤。

但是,如果您只想修改單個文件,并將其與舊版本進(jìn)行比較,所有這些操作都不需要用到git存儲庫,那該怎么辦呢?這就是本文的意義所在。本文的目標(biāo)是創(chuàng)建一個diff工具,它允許你比較一個文件的兩個版本:

  • 不需要git存儲庫和

  • 構(gòu)建在Python標(biāo)準(zhǔn)庫之上!

此外,我們的diff工具應(yīng)該能夠?qū)⒂?jì)算的差異導(dǎo)出到一個HTML文件中。要閱讀這篇文章,你只需要會Python。本文是專門為Python 3.8.2 (CPython)編寫的。你可以在GitHub上找到源代碼。就介紹到這里,讓我們來看看它吧!

unified_diff() 函數(shù)

Python標(biāo)準(zhǔn)庫包含一個名為difflib的模塊。根據(jù)文檔,這個模塊提供了用于比較序列的類和函數(shù)。此外,還有各種可用的輸出格式[1]。

在檢查該模塊時,unified_diff()函數(shù)從所有其他函數(shù)中脫穎而出。通過查看文檔提供的示例和生成的輸出,我發(fā)現(xiàn)它與我們正在尋找的差異計(jì)算函數(shù)非常相似。它需要多達(dá)8個參數(shù),但只有兩個是必需的:

  • a:字符串列表(必需)

  • b:字符串列表(必需)

  • fromfile:用于顯示第一個文件的名稱(默認(rèn)值:'')

  • tofile:用于顯示第二個文件的名稱(默認(rèn)值:'' )

  • fromfiledate:第一個文件的修改時間(默認(rèn)值: '')

  • tofiledate:第二個文件的修改時間(默認(rèn)值: '')

  • n:上下文行數(shù)*(默認(rèn)值:3)

  • lineterm:添加在控制行(帶有—、+++或@@的行)末尾的字符,以便io.IOBase.readlines()和io.IOBase.writelines()能被正確處理(默認(rèn)值:'\n')。

*上下文行用于向用戶在發(fā)生更改的地方提供上下文

實(shí)際上,unified_diff()函數(shù)會接受兩個字符串列表并對它們進(jìn)行比較。如果它們是相等的,delta就為空。如果存在任何差異,則返回各自的delta。舉個簡單的例子:你打算和你最好的朋友一起舉辦一個披薩派對,然后寫下了你需要先買的配料。為簡單起見,此購物清單是一個簡單的文本文件(my_shopping_list.txt),內(nèi)容如下所示:

你把它發(fā)送給你的朋友,他加了一種配料,因?yàn)槟銈兗依锒紱]有了:salami(意大利臘腸)。此外,他還識別出了你的打字錯誤并進(jìn)行了糾正。為了能夠正確地將這些更改傳遞給我們的diff工具,他復(fù)制了該清單并將其重命名為friends_shopping_list.txt。以下是最終的購物清單:

當(dāng)然,這是一個相當(dāng)簡單的例子,文本不是很長,所以能很容易地被人為處理。但是,讓我們增加點(diǎn)樂趣,我們繼續(xù)看這個例子。為了計(jì)算這兩個文件之間的差異,我們將它們讀入內(nèi)存,并將它們傳遞給unified_diff()函數(shù):

首先,我們導(dǎo)入了difflib和sys。其次,我們讀取這兩個文件的內(nèi)容,并將它們保存到單獨(dú)的變量(file1和file2)中。因?yàn)槲覀冃枰址斜?#xff0c;所以我們使用了readlines()。隨后,我們計(jì)算了兩個列表的delta,并通過sys.stdout.writelines()將其寫到stdout。

執(zhí)行腳本后生成的結(jié)果如下:

從輸出來看,單詞cheese沒有被修改,而是被用作上下文行,因?yàn)橄旅娴男斜恍薷牧恕omates被移除了,tomatoes和salami被加了進(jìn)去。如果您查看打印出的delta的頭部,你可以看到,我們并沒有得到有關(guān)--- 和 +++代表什么,或者它們代表什么文件的任何信息。讓我們通過將文件名添加到unified_diff()函數(shù)來調(diào)整一下腳本:

現(xiàn)在,運(yùn)行該腳本生成結(jié)果如下:

太棒了!我們實(shí)現(xiàn)了一個簡單的腳本,它可以計(jì)算并打印兩個文件內(nèi)容之間的差異。讓我們繼續(xù)并將其轉(zhuǎn)換為一個命令行工具。

構(gòu)建一個命令行工具

為了將我們的腳本轉(zhuǎn)換成一個有用的命令行工具,我們使用了Python的argparse模塊。首先,我們將之前編寫的代碼放入一個名為create_diff()的函數(shù)中,該函數(shù)接受兩個參數(shù),old_file和new_file。它們都是Path對象[2]。我們使用傳遞的Path對象來讀取它們的內(nèi)容,并使用該P(yáng)ath對象的name屬性來獲取所提供的文件的名稱。由于我們的小腳本現(xiàn)在是要更加通用,不再局限于購物清單,所以我們將我們的代碼放入一個名為diff_tool.py的新文件中(這個名稱更適合我們的腳本)。到目前為止,該腳本是這樣的:

接著,我們定義一個新函數(shù)main(),它負(fù)責(zé)總的工作流:

首先,我們定義了一個新的參數(shù)解析器。我們告訴該解析器接受兩個參數(shù),old_file_version和new_file_version。兩者都是必需的。調(diào)用parse_args()將解析命令行輸入并將輸入轉(zhuǎn)換為正確的格式。隨后,兩個命令行參數(shù)都會被訪問并且被轉(zhuǎn)換為Path對象。然后,我們使用old_file和new_file作為參數(shù)調(diào)用create_diff()。

備注:如果您想要了解更多關(guān)于argparse模塊的內(nèi)容,我強(qiáng)烈推薦Python的argparse教程[3],它提供了更詳細(xì)的Python命令行解析介紹。

現(xiàn)在,如果我們不帶任何參數(shù)執(zhí)行該腳本,它會告訴我們,哪些參數(shù)是必需的:

提供兩個購物清單后仍然會生成預(yù)期的輸出:

到目前為止,我們通過將你的簡短腳本從頭開始轉(zhuǎn)換成一個簡單的命令行工具來構(gòu)建了一個簡單的diff工具—很酷!現(xiàn)在,我們將添加更多的行來支持HTML輸出。

以HMTL格式提供差異

difflib模塊提供了一個HtmlDiff類,它可以被用來創(chuàng)建一個HTML表(或一個包含表的完整HTML文件),該表會通過將行間和行內(nèi)變?yōu)楦吡溜@示來顯示文本的并排、逐行比較。在我們的示例中,我們使用了HtmlDiff.make_file()函數(shù),它返回了一個表示完整HTML文件的字符串。后者逐行高亮顯示了任何差異。

因此,我們將我們的腳本擴(kuò)展如下:

create_diff()函數(shù)現(xiàn)在接受一個額外的第三個參數(shù)output_file,它也是一個Path對象。我們會將我們的HTML差異寫入這個文件。我們檢查是否傳遞了output_file。如果是,我們以HTML格式計(jì)算差異并將其保存到這個傳遞的文件中。

備注:我們使用w模式進(jìn)行寫操作。如果該文件已經(jīng)存在,則會被提前清空。

如果output_file沒有被傳遞,我們會計(jì)算標(biāo)準(zhǔn)差異并將其寫到stdout。

我們通過注冊一個附加的可選命令行參數(shù)--html使其以一個文件名作為輸入來擴(kuò)展了main()函數(shù)。如果提供了文件名,則將其轉(zhuǎn)換為Path對象并傳遞給create_diff()。

執(zhí)行以下命令之后,您的當(dāng)前工作目錄中就有了一個diff.html文件,你可以使用你最喜歡的瀏覽器來打開該文件去查看實(shí)際的差異。

總結(jié)

恭喜,你已經(jīng)通過本文創(chuàng)建了它!在閱讀本文時,你了解了如何使用Python的difflib模塊計(jì)算一個簡單的diff。此外,你還能夠使用Python的argparse模塊將您的短小diff腳本轉(zhuǎn)換成一個命令行工具。隨后,你添加了幾行代碼來支持以HTML作為輸出格式。

接下來是什么?你可以查看difflib文檔[1],了解計(jì)算diff的各種方法,搜索其他類型的diff,并進(jìn)一步擴(kuò)展你的diff-tool。另外,你可以查看本文的GitHub存儲庫并計(jì)算file.md和file_update.md之間的差異。你找到所有的變化了嗎?

希望你喜歡閱讀這篇文章。一定要與你的朋友和同事進(jìn)行分享哦!如果你還沒有,你可以考慮關(guān)注我的推特@DahlitzF。保持好奇心,持續(xù)編碼!

參考資料

  • difflib文檔

  • Path文檔

  • argparse文檔

  • 內(nèi)置open()函數(shù)

  • 英文原文:https://florian-dahlitz.de/blog/create-your-own-diff-tool-using-python 譯者:測試

    總結(jié)

    以上是生活随笔為你收集整理的python diff函数_使用Python创建你自己的diff工具的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。