1

我正在编写一个简单的调度服务。我不想硬编码它可以安排的所有任务,而是希望支持可以放在文件夹中并在运行时动态加载的插件。

我的计划是有一个 JSON 文件(或任何配置文件),将任务名称映射到 Python 文件(模块)的位置,该文​​件将有一个名为Plugin. 很简单,我想。当有人安排任务运行时,他们会传递任务名称和运行时间。当时间过去时,插件被加载(或重新加载)并使用传递给调度程序的任何附加参数运行。

我一直在查看imp模块以了解如何在运行时加载模块。我不确定我是想使用它们的物理位置(文件系统路径)列出插件还是使用它们的模块名称,就像你在import声明中看到的那样。它似乎imp想使用物理位置。

我得到了这个代码“工作”的两个不同版本。这是一个使用importlib

    pluginName = self.__pluginLookup[pluginName]
    module = import_module(pluginName)
    module = reload(module)  # force reload

    plugin = module.Plugin()
    return plugin

这是我写的一个imp

    path = self.__pluginLookup[pluginName]
    path, moduleName = split(path)
    moduleName, extension = splitext(moduleName)

    file, path, description = find_module(moduleName, [path])
    with file:
        module = load_module(moduleName, file, path, description)

    plugin = module.Plugin()
    return plugin

我遇到的问题是处理依赖项。如果我有一个plugin.py文件依赖于dependency.py同一文件夹中的文件,那么说import dependency似乎不起作用。相反,它从PYTHONPATH.

我怎样才能使导入相对于插件本身?

4

2 回答 2

2

您可以附加pathsys.path

import sys
sys.path.append(path)

path包含dependency.py的目录在哪里。

于 2012-09-09T02:13:30.827 回答
1

如果您有一个plugins带有 的目录__init__.py,则可以将该目录添加到sys.path. 然后里面的模块可以from . import dependency导入另一个插件。或者,如果插件本身是一个子包(即,一个有自己的目录__init__.py),那么它可以from . import dep在同一个插件from .. import dep中导入一个依赖项,或者从全局插件目录中导入一个依赖项。有了这个设置,你甚至不需要使用imp或类似的东西;您可以使用该__import__功能,该功能按模块名称工作。

但是,一个可能的问题是您说插件目录将位于“当前工作目录下”。这到底是什么意思?您的意思是您希望人们能够在驱动器上的任何位置添加插件并仍然使用它们?最好为您的应用程序提供一个中央插件目录,并将其添加到sys.path,并告诉人们将他们的插件放在那里。

于 2012-09-09T02:35:45.163 回答