2009-11-03 120 views
32

我正在編寫一個應用程序,它必須從幾個模塊(.py文件)中獲取元數據(作者,版本..等)並顯示它們。用戶選擇一個腳本並執行該腳本。 (可以像插件系統一樣從目標文件夾中添加新的腳本和舊腳本)。如何取消導入Python模塊?

首先我導入一個腳本,然後取出元數據,然後我去下一個。 但我想要導入除用戶選擇的其他模塊之外的所有其他模塊。

我該如何執行此操作?

我嘗試了這些

1. del module 
2. del sys.modules['module'] 

後者沒有工作。我試過#python,並得到了解除導入模塊並不好的解決方案,但我想知道一個乾淨的方式來實現這一點。任何想法/建議都會有所幫助。

+7

還有_is_沒有乾淨的方式來卸載模塊。你要做的一切都是通過黑客。 – 2009-11-03 16:08:59

+0

通過使用'ast'模塊解析代碼而不是導入它們來獲取元數據,例如[Epydoc](http://epydoc.sf.net),[PyDoctor](http://codespeak.net/~mwh)/pydoctor /)和[Sphinx](http://sphinx.pocoo.org)。 – Allen 2011-04-01 21:45:21

回答

18

我覺得this post應該幫助你

編輯: ,以確保這些信息的可用性(在情況下,鏈接死亡或者類似的東西),我將包括來自tutor mailing list原來這裏的消息:


在06年8月14日,迪克·穆爾斯說:

其實,我的問題是,利用空閒做一些0123導入後模塊和變量的初始化,如何返回到它的 初始條件而不關閉並重新打開它。

因此,例如後我做了

>>> import math, psyco 
>>> a = 4**23 

我怎樣才能消滅那些出來而不關閉空閒? (我用了才知道怎麼樣,但是我忘了。)

嗨迪克,

通常這需要從「模塊註冊表中刪除,並在代碼中移除 引用它。如果你有一個真的很好用的模塊(如 一個配置參數導入到每個模塊),那麼你將有一個 額外的步驟從每個模塊中刪除它。 「,那麼你將無法釋放該模塊並參考模塊e很容易(是從該模塊獲得,還是從 導入第三個模塊?請參閱「如果偏執:下面的代碼)

下面的函數從Python解釋刪除模塊用名稱 ‘偏執’參數變量名稱的列表,以從每一個其他 模塊除去(假定被與刪除如果你的函數和類在不同的模塊中被命名爲相同的,這可能會給你的解釋器帶來問題,一個常見的問題是異常的「錯誤」,很多庫中有一個 「catch-all」異常,稱爲「錯誤」。如果您還將 異常命名爲「錯誤」,並決定將其包含在偏執性列表中,那麼 會出現很多其他異常對象。

def delete_module(modname, paranoid=None): 
    from sys import modules 
    try: 
     thismod = modules[modname] 
    except KeyError: 
     raise ValueError(modname) 
    these_symbols = dir(thismod) 
    if paranoid: 
     try: 
      paranoid[:] # sequence support 
     except: 
      raise ValueError('must supply a finite list for paranoid') 
     else: 
      these_symbols = paranoid[:] 
    del modules[modname] 
    for mod in modules.values(): 
     try: 
      delattr(mod, modname) 
     except AttributeError: 
      pass 
     if paranoid: 
      for symbol in these_symbols: 
       if symbol[:2] == '__': # ignore special symbols 
        continue 
       try: 
        delattr(mod, symbol) 
       except AttributeError: 
        pass 

那麼你應該能夠使用此類似:

delete_module('psyco') 

delete_module('psyco', ['Psycho', 'KillerError']) 
# only delete these symbols from every other module 
# (for "from psyco import Psycho, KillerError" statements) 

-Arcege

+3

如果鏈接永遠死去,你能總結一下這裏的內容嗎? – 2009-11-03 16:06:18

+0

thanx的鏈接...但有沒有其他方式來獲取其他元數據,然後導入。 – Sriram 2009-11-03 16:17:32

+0

有沒有這個代碼的真正用途,永遠。 – Allen 2011-04-01 21:45:52

5

建議:導入你的模塊使用動態__import__

例如

module_list = ['os', 'decimal', 'random'] 
for module in module_list: 
    x = __import__(module) 
    print 'name: %s - module_obj: %s' % (x.__name__, x) 

會產生:

name: os - module_obj: <module 'os' from '/usr/lib64/python2.4/os.pyc'> 
name: decimal - module_obj: <module 'decimal' from '/usr/lib64/python2.4/decimal.pyc'> 
name: random - module_obj: <module 'random' from '/usr/lib64/python2.4/random.pyc'> 

雖然,這不會真正從模塊註冊表中刪除它。下一次導入時,它不會重新讀取包/模塊文件,也不會執行它。爲了實現這個目標,你可以簡單地修改上面的代碼片段是這樣的:

import sys 
module_list = ['os', 'decimal', 'random', 'test1'] 
for module_name in module_list: 
    x = __import__(module_name) 
    print 'name: %s - module_obj: %s' % (x.__name__, x) 
    del x 
    sys.modules.pop(module_name) 
2

我知道這個帖子已經過時了,但我只是遇到了這個問題,並在鬥爭它在過去的幾天裏。現在我得出了一個可以完美解決這個問題的結論。請參閱下面的示例代碼:

try: 
    theMod = sys.modules['ModNeedToBeDel'] 
except: 
    theMod = None 
if theMod: 
    del sys.modules['ModNeedToBeDel'] 

#The extra try/except below is because I implemented the block in a module of a sub-package; this ModNeedToBeDel in my case was imported either by the toppest level Main code, or by the other sub-package modules. That's why I need two different try/except. 

try: 
    theMod = sys.modules['UpperFolder.ModNeedToBeDel'] 
except: 
    theMod = None 
if theMod: 
    del sys.modules['UpperFolder.ModNeedToBeDel'] 
import ModNeedToBeDel # or UpperFolder.ModNeedToBeDel here 

注意del sys.modules[theMod]是行不通的,因爲它只是刪除了參考,而不是實際的ModNeedToBeDel

希望這可以幫助別人,讓他們不必在這個問題上奮鬥幾天!