1. 程式人生 > >Python 依賴庫管理哪家強?pipreqs、pigar、pip-tools、pipdeptree 任君挑選

Python 依賴庫管理哪家強?pipreqs、pigar、pip-tools、pipdeptree 任君挑選

在 Python 的專案中,如何管理所用的全部依賴庫呢?最主流的做法是維護一份“requirements.txt”,記錄下依賴庫的名字及其版本號。

那麼,如何來生成這份檔案呢?在上篇文章《由淺入深:Python 中如何實現自動匯入缺失的庫?》中,我提到了一種常規的方法:

pip freeze > requirements.txt

這種方法用起來方便,但有幾點不足:

  • 它搜尋依賴庫的範圍是全域性環境,因此會把專案之外的庫加入進來,造成冗餘(一般是在虛擬環境中使用,但還是可能包含無關的依賴庫)
  • 它只會記錄以“pip install”方式安裝的庫
  • 它對依賴庫之間的依賴關係不做區分
  • 它無法判斷版本差異及迴圈依賴等情況
  • …………

可用於專案依賴管理的工具有很多,本文主要圍繞與 requirements.txt 檔案相關的、比較相似卻又各具特色的 4 個三方庫,簡要介紹它們的使用方法,羅列一些顯著的功能點。至於哪個是最好的管理方案呢?賣個關子,請往下看……

pipreqs

這是個很受歡迎的用於管理專案中依賴庫的工具,可以用“pip install pipreqs”命令來安裝。它的主要特點有:

  • 搜尋依賴庫的範圍是基於目錄的方式,很有針對性
  • 搜尋的依據是指令碼中所 import 的內容
  • 可以在未安裝依賴庫的環境上生成依賴檔案
  • 查詢軟體包資訊時,可以指定查詢方式(只在本地查詢、在 PyPi 查詢、或者在自定義的 PyPi 服務)

基本的命令選項如下:

Usage:
    pipreqs [options] <path>

Options:
    --use-local           Use ONLY local package info instead of querying PyPI
    --pypi-server <url>   Use custom PyPi server
    --proxy <url>         Use Proxy, parameter will be passed to requests library. You can also just set the
                          environments parameter in your terminal:
                          $ export HTTP_PROXY="http://10.10.1.10:3128"
                          $ export HTTPS_PROXY="https://10.10.1.10:1080"
    --debug               Print debug information
    --ignore <dirs>...    Ignore extra directories
    --encoding <charset>  Use encoding parameter for file open
    --savepath <file>     Save the list of requirements in the given file
    --print               Output the list of requirements in the standard output
    --force               Overwrite existing requirements.txt
    --diff <file>         Compare modules in requirements.txt to project imports.
    --clean <file>        Clean up requirements.txt by removing modules that are not imported in project.

其中需注意,很可能遇到編碼錯誤:UnicodeDecodeError: 'gbk' codec can't decode byte 0xae in 。需要指定編碼格式“--encoding=utf8”。

在已生成依賴檔案“requirements.txt”的情況下,它可以強行覆蓋、比對差異以及清除不再使用的依賴項。

pigar

pigar 同樣可以根據專案路徑來生成依賴檔案,而且會列出依賴庫在檔案中哪些位置使用到了。這個功能充分利用了 requirements.txt 檔案中的註釋,可以提供很豐富的資訊。

pigar 對於查詢真實的匯入源很有幫助,例如bs4 模組來自beautifulsoup4 庫,MySQLdb 則來自於MySQL_Python 庫。可以通過“-s”引數,查詢真實的依賴庫。

$ pigar -s bs4 MySQLdb

它使用解析 AST 的方式,而非正則表示式的方式,可以很方便地從 exec/eval 的引數、文件字串的文件測試中提取出依賴庫。

另外,它對於不同 Python 版本的差異可以很好地支援。例如,concurrent.futures 是 Python 3.2+ 的標準庫,而在之前早期版本中,需要安裝三方庫futures ,才能使用它。pigar 做到了有效地識別區分。(PS:pipreqs 也支援這個識別,詳見這個合入:https://github.com/bndr/pipreqs/pull/80)

pip-tools

pip-tools 包含一組管理專案依賴的工具:pip-compile 與 pip-sync,可以使用命令“pip install pip-tools”統一安裝。它最大的優勢是可以精準地控制專案的依賴庫。

兩個工具的用途及關係圖如下:

pip-compile 命令主要用於生成依賴檔案和升級依賴庫,另外它可以支援 pip 的“Hash-Checking Mode ”,並支援在一個依賴檔案中巢狀其它的依賴檔案(例如,在 requirements.in 檔案內,可以用“-c requirements.txt”方式,引入一個依賴檔案)。

它可以根據 setup.py 檔案來生成 requirements.txt,假如一個 Flask 專案的 setup.py 檔案中寫了“install_requires=['Flask']”,那麼可以用命令來生成它的所有依賴:

$ pip-compile
#
# This file is autogenerated by pip-compile
# To update, run:
#
#    pip-compile --output-file requirements.txt setup.py
#
click==6.7                # via flask
flask==0.12.2
itsdangerous==0.24        # via flask
jinja2==2.9.6             # via flask
markupsafe==1.0           # via jinja2
werkzeug==0.12.2          # via flask

在不使用 setup.py 檔案的情況下,可以建立“requirements.in”,在裡面寫入“Flask”,再執行“pip-compile requirements.in”,可以達到跟前面一樣的效果。

pip-sync 命令可以根據 requirements.txt 檔案,來對虛擬環境中進行安裝、升級或解除安裝依賴庫(注意:除了 setuptools、pip 和 pip-tools 之外)。這樣可以有針對性且按需精簡地管理虛擬環境中的依賴庫。

另外,該命令可以將多個“*.txt”依賴檔案歸併成一個:

$ pip-sync dev-requirements.txt requirements.txt

pipdeptree

它的主要用途是展示 Python 專案的依賴樹,通過有層次的縮排格式,顯示它們的依賴關係,不像前面那些工具只會生成扁平的並列關係。

除此之外,它還可以:

  • 生成普遍適用的 requirements.txt 檔案
  • 逆向查詢某個依賴庫是怎麼引入進來的
  • 提示出相互衝突的依賴庫
  • 可以發現迴圈依賴,進行告警
  • 生成多種格式的依賴樹檔案(json、graph、pdf、png等等)

它也有缺點,比如無法穿透虛擬環境。如果要在虛擬環境中工作,必須在該虛擬環境中安裝 pipdeptree。因為跨虛擬環境會出現重複或衝突等情況,因此需要限定虛擬環境。但是每個虛擬環境都安裝一個 pipdeptree,還是挺讓人難受的。

好啦,4 種庫介紹完畢,它們的核心功能都是分析依賴庫,生成 requirements.txt 檔案,同時,它們又具有一些差異,補齊了傳統的 pip 的某些不足。

本文不對它們作全面的測評,只是選取了一些主要特性進行介紹,好在它們安裝方便(pip install xxx),使用也簡單,感興趣的同學不妨一試。

更多豐富的細節,請查閱官方文件:

https://github.com/bndr/pipreqs

https://github.com/damnever/pigar

https://github.com/jazzband/pip-tools

https://github.com/naiquevin/pipdeptree

公眾號【Python貓】, 本號連載優質的系列文章,有喵星哲學貓系列、Python進階系列、好書推薦系列、技術寫作、優質英文推薦與翻譯等等,歡迎關注哦