2009-11-03 117 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

希望这可以帮助别人,让他们不必在这个问题上奋斗几天!