這裏主要用了兩個庫:pipdeptree和pyecharts。
pipdeptree用來解析所有庫的依賴關係。
pyecharts用來顯示依賴的網絡關係。
通常的方法應該是通過輸入下面命令:
pipdeptree --json-tree > pkg.json
得到關係樹文件,然後解析該文件並在pyecharts顯示即可。
不過我不想解析json文件了。
這裏是直接輸入pipdeptree命令,得到控制檯輸出,然後解析字符串來做的,比較暴力。
控制檯輸出爲下面這種格式:
apturl==0.5.2 autopep8==2.0.2 ├── pycodestyle [required: >=2.10.0, installed: 2.10.0] └── tomli [required: Any, installed: 2.0.1] bcrypt==3.2.0 blendmodes==2022 ├── aenum [required: >=3.1.7,<4, installed: 3.1.12] ├── deprecation [required: >=2.1.0,<3, installed: 2.1.0] │ └── packaging [required: Any, installed: 23.0] ├── numpy [required: >=1.22.1,<2, installed: 1.24.1] └── Pillow [required: >=9.0.0,<10, installed: 9.0.1]
發現根據字符串中的"─"字符和該字符所在的位置,就能知道該庫是根節點還是被第幾層依賴的節點。
然後需要確定前後庫的依賴連接,確定的方法也比較暴力,最後轉爲pyecharts輸出即可。
代碼如下:
from pyecharts.charts import Graph from pyecharts import options as opts import subprocess # 調用系統命令並獲取結果 pip install pipdeptree result = subprocess.run('pipdeptree', capture_output=True, text=True) output = result.stdout output = output.split('\n') depIndex = [] depName = [] for v in output: num = v.find('──') if num==-1: depIndex.append(0) name = v.split('==') depName.append(name[0]) else: depIndex.append(num//4+1) name = v.split('──') name = name[1].split(' ') depName.append(name[1]) depIndex.pop() depName.pop() maxId = max(depIndex) nodeNames =list(set(depName)) dicts={} for nodeName in nodeNames: dicts[nodeName] = 5 links = [] while maxId!=0: findMax = False for i in range(len(depIndex)): if i!=0: if depIndex[i]==maxId: link = {"source":depName[i-1],"target":depName[i]} if link not in links: dicts[depName[i]] = dicts[depName[i]] + 2 links.append(link) depIndex.pop(i) depName.pop(i) findMax = True break if findMax==False: maxId= maxId-1 nodes = [] for nodeName in nodeNames: node = {"name":nodeName,"symbolSize":dicts[nodeName]} nodes.append(node) graph = Graph(init_opts=opts.InitOpts(width="1920px", height="1080px")) graph.add("", nodes, links) graph.render('show.html')
所有連接效果如下,球越大代表被依賴的越多:
局部效果如下,選中節點後相關節點高亮: