我正在编写一个应用程序,它必须从几个模块(.py文件)中获取元数据(作者,版本......等)并显示它们.用户选择脚本并执行脚本.(可以添加新脚本,并从目标文件夹中获取旧脚本,就像插件系统一样).
首先,我导入一个脚本,然后取出元数据,然后我去下一个.但我想取消导入所有其他模块,除了用户选择的模块.
我该如何实现呢?
我试过这些
1. del module
2. del sys.modules['module']
Run Code Online (Sandbox Code Playgroud)
后者不起作用.我试过#python并得到了一个解决方案,即取消导入模块并不好,但我想知道一种干净的方法来实现它.任何想法/建议都会有所帮助.
gab*_*tub 18
我认为这篇文章可以帮到你
编辑:为确保此信息的可用性(如果链接死亡或类似的东西),我将在此处包含来自教师邮件列表的原始邮件:
6月14日,Dick Moores写道:
实际上,我的问题是,在使用IDLE进行模块导入和初始化变量之后,如何将其返回到初始条件而不关闭并重新打开它.
所以,例如在我完成之后
Run Code Online (Sandbox Code Playgroud)>>> import math, psyco >>> a = 4**23如何在不关闭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
建议:使用动态导入模块 __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)