2017-02-09 50 views
3

如果你輸入:得到一個安裝包的描述不實際導入它

import somemodule 
help(somemodule) 

它會打印出分頁包描述。我需要獲得與字符串相同的描述,但不需要將此包導入當前名稱空間。這可能嗎?當然,因爲在Python中任何東西都是可能的,但是這樣做的最優雅/蟒蛇的方式是什麼?

邊注:通過優雅的方式,我的意思,而無需打開一個單獨的進程,並捕獲標準輸出...;)

換句話說,是有辦法窺視到一個未匯入,但安裝的軟件包,並查看其描述?也許與importlib.abc.InspectLoader?但我不知道如何讓它按我需要的方式工作。

更新:我不需要不污染命名空間,但也可以做到這一點,而不會留下任何自己或依賴模塊的痕跡在內存和sys.modules等。像它從來沒有真正導入。

更新:之前有人問我爲什麼我需要它 - 我想列出所有已安裝的Python包與他們的描述。但在此之後,我不想讓它們在sys.modules中導入,也不會佔用內存中的過多空間,因爲可能會有很多空間。

+0

感謝您的澄清。這使得它成爲可能 –

回答

0

好吧,如果你只擔心保持全局命名空間整潔,你總是可以導入功能:

>>> def get_help(): 
...  import math 
...  help(math) 
... 
>>> math 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'math' is not defined 
+0

麻煩的是,它仍然加載在內存和'sys.modules'中。我不清楚這一點,所以我會更新這個問題。 –

-1

我會建議不同的方法,如果我理解正確的話,你想讀一個包的一部分,而不導入它(甚至在一個局部範圍的函數內)。我建議一種方法是通過訪問(python_path)/ Lib/site-packages /(package_name)/並讀取各個文件的內容作爲導入模塊的替代方法,以便Python可以。

+0

這有時會起作用,但是很多Python docstrings都是從格式化表達式到設置'__doc__'屬性的完全不同的代碼生成的。在這些情況下,您將最終重新實現解釋器來獲取文檔字符串。 –

1

您需要導入模塊以獲取幫助字符串的原因是,在許多情況下,幫助字符串實際上是在代碼中生成的。解析這個包的文本以獲取字符串是毫無意義的,因爲您必須編寫一個小的Python解釋器來重建實際的字符串。

也就是說,有些方法可以根據this answer完全刪除暫時導入的模塊,該模塊總結了2003年左右Python郵件列表中出現的一個線程:http://web.archive.org/web/20080926094551/http://mail.python.org/pipermail/python-list/2003-December/241654.html。這裏描述的方法通常只在模塊沒有在別處被引用時才起作用。否則,模塊將被卸載,因爲import將從頭開始重新加載它,而不是使用現有的sys.modules條目,但模塊仍將存在內存中。

這是一個函數,可以完成您想要的功能,如果該模塊看起來沒有被卸載,甚至會打印警告。不像在鏈接答案提出的解決方案,這個功能確實處理加載模塊的所有副作用,其中包括一個事實,即導入一個包可能引入其它外部包到sys.modules

import sys, warnings 
def get_help(module_name): 
    modules_copy = sys.modules.copy() 
    module = __import__(module_name) 
    h = help(module) 
    for modname in list(sys.modules): 
     if modname not in modules_copy: 
      del sys[modname] 
    if sys.getrefcount(module) > 1: 
     warnings.warn('Module {} is likely not to be completely wiped'.format(module_name)) 
    del module 
    return h 

的原因,我做最後一個循環中的關鍵字列表是,在遍歷它時修改字典(或任何其他可迭代的)是不可取的。至少在Python 3中,dict.keys()返回由字典本身支持的迭代,而不是凍結副本。我不確定是否需要h = ...return h,但在最壞的情況下,h只是None

+0

感謝日誌,我會試一試。但仍然感覺有點脆弱。因此,我傾向於使用單獨的進程來導入模塊,將所需的字符串回滾,然後刪除此進程(es)。這似乎是錯誤的證據,而且我不會在獲取數據時阻止我的主流程,我認爲這需要一段時間。 –

+0

你的方式確實更可靠。你應該發佈你自己的答案。此外,[這個問題](http://stackoverflow.com/q/42142660/2988730)來自上面的答案。 –

+0

一旦我的解決方案正常工作,我將發佈我的答案。 –

相關問題