如何查找python代碼中所有未使用到的from與import的類庫,例:from a import b# 下面的操作沒用到b
2 回答

慕沐林林
TA貢獻2016條經驗 獲得超9個贊
假定你的代碼中都沒有直接從locals()/globals()中獲取b的引用,那這還是比較容易的,下面給你舉個例子吧。
比如這段代碼:
from a import bb
你可以用python的compiler模塊去解析它:
import compilercompiler.parse('from a import b\nb')
得到的輸出為這段代碼的AST(abstract syntax tree)
Module(None, Stmt([From('a', [('b', None)], 0), Discard(Name('b'))]))
有了AST,你就可以很容易地去處理它了,為了更簡單一點,可以這樣:
import parserst = parser.suite('from a import b\nb') print parser.st2list(st)
輸出是:
[257, [267, [268, [269, [281, [283, [1, "from"], [288, [1, "a"]], [1, "import"], [286, [284, [1, "b"]]]]]], [4, ""]]], [267, [268, [269, [270, [327, [304, [305, [306, [307, [308, [310, [311, [312, [313, [314, [315, [316, [317, [318, [1, "b"]]]]]]]]]]]]]]]]]], [4, ""]], [0, ""]]
這就是一棵用list構成的樹了,你要做的事情就是先序遍歷,遍歷的過程中用一個dict保存所有被import的name,遇到引用name的時候,記錄它是否出現過,最后輸出dict中沒有出現過的name即可。
另外,如果有這樣的情況:
from a import bb = 123 #后續對b的引用與import的b無關
你也可以特殊處理一下賦值操作,檢查被賦值的name是否在dict中且沒有被引用過
,如果是,輸出它,從dict里刪除,然后繼續。
EDIT
補充一下,有以下這些import語句需要考慮:
//from Python/Include/graminit.h
#define import_stmt 281#define import_name 282#define import_from 283#define import_as_name 284#define import_as_names 286

慕村225694
TA貢獻1880條經驗 獲得超4個贊
樓主想要干的事情,在程序靜態分析中,被稱為DCE(無用代碼的刪除)。自己實現一個也不是不可以,不過如果急用的話就不太合適了。
現成的插件/庫也是有很多的。我用過一段時間的pyflakes,它是一個代碼檢查插件,不僅可以滿足樓主的要求,還有更多的功能。以樓主的代碼為例,
$ echo "from a import b" > test.py$ pyflakes test.pytest.py:1: 'b' imported but unused
大概就是這樣。
添加回答
舉報
0/150
提交
取消