编辑:这是32位的Python 2.7.6。
我刚加载和删除的模块现在无法在导入时找到。笏?
我最近一直在使用名为yapsy
的插件系统,它不适合我的应用程序(聊天机器人),所以我决定自己编写。
一切都在大部分时间都有效,但我遇到了一个奇怪的问题 - 如果我加载一个模块,卸载它(并删除所有引用,以便它不在sys.modules中)并尝试再次加载它,importlib无法找到它。
违规代码为on GitHub,但我也会在下方粘贴相关内容。
def load_plugin(self, name):
name = name.lower()
if name not in self.info_objects:
return PluginState.NotExists
if name in self.objects:
return PluginState.AlreadyLoaded
info = self.info_objects[name]
for dep in info.core.dependencies:
dep = dep.lower()
if dep not in self.objects:
return PluginState.DependencyMissing
# module = plugins.control
module = "%s.%s" % (self.module, info.module)
try:
self.log.trace("Module: %s" % module)
obj = None
if module in sys.modules:
# Always False
self.log.trace("Module exists, reloading..")
reload(sys.modules[module])
module_obj = sys.modules[module]
else:
module_obj = importlib.import_module(module)
self.log.trace("Module object: %s" % module_obj)
for name_, clazz in inspect.getmembers(module_obj):
self.log.trace("Member: %s" % name_)
if inspect.isclass(clazz):
self.log.trace("It's a class!")
if clazz.__module__ == module:
self.log.trace("It's the right module!")
for parent in clazz.__bases__:
if parent == PluginObject:
self.log.trace("It's the right subclass!")
obj = clazz()
if obj is None:
self.log.error(
"Unable to find plugin class for plugin: %s" % info.name
)
return PluginState.LoadError
self.objects[name] = obj
except ImportError:
self.log.exception("Unable to import plugin: %s" % info.name)
self.log.debug("Module: %s" % module)
return PluginState.LoadError
except Exception:
self.log.exception("Error loading plugin: %s" % info.name)
return PluginState.LoadError
else:
try:
info.module = module
info.core.module = module
info.set_plugin_object(obj)
obj.add_variables(info, self.factory_manager)
obj.logger = getLogger(info.name)
obj.setup()
except Exception:
self.log.exception("Error setting up plugin: %s" % info.name)
return PluginState.LoadError
else:
self.objects[name] = obj
return PluginState.Loaded
def unload_plugin(self, name):
name = name.lower()
if name not in self.objects:
return PluginState.NotExists
obj = self.objects[name]
self.factory_manager.commands.unregister_commands_for_owner(obj)
self.factory_manager.event_manager.remove_callbacks_for_plugin(obj)
self.factory_manager.storage.release_files(obj)
try:
obj.deactivate()
except Exception:
self.log.exception("Error deactivating plugin: %s" % obj.info.name)
del self.objects[name]
return PluginState.Unloaded
使用时的一些示例输出..
09 Sep 2014 - 09:29:39 | Commands | INFO | irc-esper | <g:#Ultros-test> .pl load control
09 Sep 2014 - 09:29:39 | irc-esper | INFO | -> *#Ultros-test* Loaded plugin: Control
09 Sep 2014 - 09:29:42 | Commands | INFO | irc-esper | <g:#Ultros-test> .pl unload control
09 Sep 2014 - 09:29:42 | irc-esper | INFO | -> *#Ultros-test* Unloaded plugin: Control
09 Sep 2014 - 09:29:43 | Commands | INFO | irc-esper | <g:#Ultros-test> .pl load control
09 Sep 2014 - 09:29:43 | Plugins | ERROR | Unable to import plugin: Control
Traceback (most recent call last):
File "E:\Ultros\Projects\Ultros\Ultros\system\plugins\manager.py", line 175, in load_plugin
module_obj = importlib.import_module(module)
File "Z:\Python\App\lib\importlib\__init__.py", line 37, in import_module
__import__(name)
ImportError: No module named plugins.control
所以,显然,这里发生了一些奇怪的事情。 plugins.control
显然存在并且第一次成功加载 - 它在被卸载并再次尝试加载后仍然存在 - 所以..我真的不知道发生了什么。
我可以看到该模块正在丢失所有引用 - 这就是我想要的 - 所以从sys.modules中删除了,但是,我真的不明白这种行为。
有什么想法吗?
答案 0 :(得分:0)
发现它!
经过一番乱搞后,我注意到我忽略了每个插件加载时都设置了info.module
,每次都是"plugins."
的前缀。
control
plugins.control
plugins.plugins.control
因此导致ImportError。