【Python】可視化Python庫的依賴關係

這裏主要用了兩個庫: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')

所有連接效果如下,球越大代表被依賴的越多:

局部效果如下,選中節點後相關節點高亮:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章