导入的模块消失了吗?

时间:2014-09-09 09:11:34

标签: python import

编辑:这是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中删除了,但是,我真的不明白这种行为。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

发现它!

经过一番乱搞后,我注意到我忽略了每个插件加载时都设置了info.module,每次都是"plugins."的前缀。

  • - &GT; control
  • - &GT; plugins.control
  • - &GT; plugins.plugins.control

因此导致ImportError。