【问题标题】:Python3 plugin systemPython3插件系统
【发布时间】:2012-01-23 22:37:55
【问题描述】:

我正在尝试创建一个类似于 yapsy 的插件框架(不幸的是 yapsy 不兼容 python3)。

我的代码如下所示:

root
   main.py
   plugins/
       __init__.py
       PluginManager.py
       UI/
           __init__.py
           textui.py

在 PluginManager.py 我定义了以下类:

class PluginMetaclass(type):
    def __init__(cls, name, base, attrs):
        if not hasattr(cls, 'registered'):
            cls.registered = []
        else:
            cls.registered.append((name,cls))

class UI_Plugins(object):
    __metaclass__ = PluginMetaclass

    #...some code here....

    def load():
         #...some code here too...

        if "__init__" in  os.path.basename(candidate_filepath):
            sys.path.append(plugin_info['path'])
        try:
            candidateMainFile = open(candidate_filepath+".py","r")  
            exec(candidateMainFile,candidate_globals)
        except Exception as e:
            logging.error("Unable to execute the code in plugin: %s" % candidate_filepath)
            logging.error("\t The following problem occured: %s %s " % (os.linesep, e))
            if "__init__" in  os.path.basename(candidate_filepath):
                sys.path.remove(plugin_info['path'])
            continue

其中 Candidate_filepath 包含插件路径。

textui.py 包含以下内容:

from root.plugins.PluginManager import UI_Plugins

class TextBackend(UI_Plugins):
    def run(self):
        print("c")

当我尝试加载插件时出现此错误:

No module named plugins.PluginManager 

我该如何解决这个问题?

【问题讨论】:

    标签: python plugin-architecture


    【解决方案1】:
    1. 为了有一个包,你需要在一个目录中有一个__init__.py 文件。它可能是空的,但它必须在“root”和“plugin”目录中。
    2. 目录的名称就是命名空间的名称,因此它们必须仔细匹配。在您的情况下,您需要使用from root.plugin.PluginManager import UI_Plugins
    3. 最后,为了使导入工作,包必须在您的 PYTHONPATH 中(参见语言文档中的The Module Search Path)。您可以通过将目录添加到 PYTHONPATH 环境变量来执行此操作,也可以在代码中将其添加到 sys.path 列表中。

    【讨论】:

    • 对不起!我犯了一个错误!抱歉,我更正了原帖。
    【解决方案2】:

    导入声明

    from root.plugins.PluginManager import UI_Plugins
    

    不起作用,因为root 不是包。

    但是,如果应用程序启动时

    python3 root/main.py
    

    那么root 实际上需要成为一个包。

    您只需将textui.py 中的导入语句更改为

    from plugins.PluginManager import UI_Plugins
    

    一切都应该正常工作。

    之所以如此,是因为当前运行脚本的目录总是自动添加到sys.path 的开头。在您的情况下,这将是root,并且由于plugins 是该目录中的一个包,它可以直接从您的应用程序中的任何位置导入。因此,只要您的 main 脚本保留在原处,就不需要进行任何其他路径操作。

    【讨论】:

      【解决方案3】:

      抱歉,这当然不是您问题的直接答案,但如果您尝试为 python3 开发非常接近 yapsy 的东西,那么您可能会对我发布的新版本 yapsy 感兴趣python3兼容包:

      https://sourceforge.net/projects/yapsy/files/Yapsy-1.9/

      (参见 Yapsy-1.9_python3-py3.2.egg 或 Yapsy-1.9-python3.tar.gz)

      特定分支上的源代码:

      http://yapsy.hg.sourceforge.net/hgweb/yapsy/yapsy/file/91ea058181ee

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多