2017-10-19 144 views
1

我想訪問某種Python中的導入依賴項跟蹤,如果有的話。如何獲取python模塊導入的模塊列表

我決定在我的模塊中添加一個__dependencies__字典,它描述了模塊導入的所有模塊的版本。

我想要一個自動的方式來獲取我的模塊導入的模塊列表。最好在模塊的最後一行。

ModuleFinder(由How to list imports within a Python module?建議)將不起作用,因爲應該對已經裝載的模塊進行檢查。

ModuleFinder的另一個問題是它檢查Python 腳本(與if __name__ == '__main__'分支),而不是模塊。

如果我們考慮一個玩具腳本script.py:

if __name__ == '__main__': 
    import foo 

那麼結果是:

>>> mf = ModuleFinder 
>>> mf.run_script('script.py') 
>>> 'foo' in mf.modules 
True 

如果腳本導入爲一個模塊,它應該是假的。

我不想列出所有導入的模塊 - 只有我的模塊導入的模塊 - 所以sys.modules(建議What is the best way of listing all imported modules in python?)會返回太多。

我可以從模塊代碼的開頭和結尾比較sys.modules的快照。但這樣我會錯過我的模塊使用的所有模塊,但之前由其他任何模塊導入。

列出模塊從中導入對象的模塊也很重要。

如果我們考慮一個玩具模塊example.py:

from foo import bar 
import baz 

那麼結果應該是這樣的:

>>> import example 
>>> moduleImports(example) 
{'foo': <module 'foo' from ... >, 
'baz': <module 'baz' from ...>} 

(它可能包含也模塊中引入遞歸或foo.bar給出的酒吧是一個模塊)。 (根據How to list imported modules?)的globls()

使用需要我手動處理非模塊導入,如:

from foo import bar 
import bar 

我怎樣才能避免這種情況?

到目前爲止,我的解決方案還存在另一個問題。 PyCharm傾向於在重構時清理我的手動導入,這使得它很難保持工作。

+0

目前尚不清楚爲什麼你認爲'ModuleFinder'不起作用。事實上,它肯定是唯一能*可能工作的東西。您還將如何區分已經加載的模塊和由模塊首先導入的模塊?以及如何識別不在模塊全局範圍內的導入(例如內部函數)? – ekhumoro

+0

@ekhumoro我不知道爲什麼SO沒有通知我您的評論。看到編輯的問題,然後請讓我知道,所以我可以刪除[編輯]標籤。 – abukaj

+0

您聲稱'ModuleFinder'不能用於模塊顯然是錯誤的 - 請參見[python文檔中的示例](https://docs.python.org/2/library/modulefinder.html#example-usage-of- modulefinder)。我沒有看到你不應該使用它的任何其他很好的理由。 – ekhumoro

回答

0

可以使用inspect moudule

例如:

import inspect 
import os 
m = inspect.getmembers(os) # get module content 
filter(lambda x: inspect.ismodule(x[1]), m) # filter dependant modules 

這裏有一個live example

如果你想剛纔導入的本地模塊使用:

filter(lambda x: inspect.ismodule(x[1]), locals().items()) # filter dependant modules 

另一個live example

+0

謝謝。不幸的是,它有與我目前的解決方案相同的缺點(過濾'globals()')。它忽略了非模塊導入(如果從foo導入欄中''foo'不被注意到)。 – abukaj

+0

@abukaj,我不認爲你會得到,除非手動指定,因爲實際上foo沒有被使用,因爲python沒有把它帶到範圍:/ – Netwave

+0

我希望有Python模塊中的某種導入跟蹤。 – abukaj