如何取消导入Python模块?

Sri*_*ram 34 python

我正在编写一个应用程序,它必须从几个模块(.py文件)中获取元数据(作者,版本......等)并显示它们.用户选择脚本并执行脚本.(可以添加新脚本,并从目标文件夹中获取旧脚本,就像插件系统一样).

首先,我导入一个脚本,然后取出元数据,然后我去下一个.但我想取消导入所有其他模块,除了用户选择的模块.

我该如何实现呢?

我试过这些

1. del module
2. del sys.modules['module']
Run Code Online (Sandbox Code Playgroud)

后者不起作用.我试过#python并得到了一个解决方案,即取消导入模块并不好,但我想知道一种干净的方法来实现它.任何想法/建议都会有所帮助.

gab*_*tub 18

我认为这篇文章可以帮到你

编辑:为确保此信息的可用性(如果链接死亡或类似的东西),我将在此处包含来自教师邮件列表的原始邮件:


6月14日,Dick Moores写道:

实际上,我的问题是,在使用IDLE进行模块导入和初始化变量之后,如何将其返回到初始条件而不关闭并重新打开它.

所以,例如在我完成之后

>>> import math, psyco
>>> a = 4**23
Run Code Online (Sandbox Code Playgroud)

如何在不关闭IDLE的情况下擦除它们?(我曾经知道如何,但我已经忘记了.)

嗨迪克,

通常这需要从"模块注册表中删除并删除代码中对它的引用.如果你有一个非常好用的模块(比如将一个配置参数导入到每个模块中),那么你将有一个额外的步骤将其从每个模块.另外,如果您使用"来自psyco import ...",那么您将无法轻松释放模块和模块的引用(是从该模块,还是从第三个模块导入?看"如果偏执:下面的代码".

下面的函数从Python解释器中按名称删除模块,"paranoid"参数是要从每个其他模块中删除的变量名列表(假设与模块一起删除).对偏执的param非常小心; 如果您的函数和类在不同的模块中命名相同,则可能会导致解释器出现问题.这种情况的一个常见现象是异常的"错误".很多库在模块中都有一个名为"error"的"catch-all"异常.如果您还将异常命名为"error"并决定将其包含在偏执列表中......那么还会有很多其他异常对象.

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
Run Code Online (Sandbox Code Playgroud)

然后你应该可以这样使用:

delete_module('psyco')
Run Code Online (Sandbox Code Playgroud)

要么

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

-Arcege

  • 如果链接死了,你能在这里总结一下内容吗? (3认同)

Ehs*_*ghi 6

建议:使用动态导入模块 __import__

例如

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

会产生:

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'>
Run Code Online (Sandbox Code Playgroud)

虽然,这不会真正从模块注册表中删除它.下次导入时,它不会重新读取包/模块文件,也不会执行它.要实现这一点,您只需修改上面的代码片段,如下所示:

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)
Run Code Online (Sandbox Code Playgroud)


小智 6

我最近发现这篇文章https://www.geeksforgeeks.org/reloading-modules-python/等适用于 Python 3.4 或更高版本

import importlib
importlib.reload(module) 
Run Code Online (Sandbox Code Playgroud)