我有一个纯Python的项目,带有一个基本的插件系统:你编写一个模块来定义一个具有特定接口和名称的类,程序导入模块,然后根据需要实例化该类。
目前,插件都来自特定文件夹(主.py文件所在的子目录)。我希望能够将它们放在磁盘上的其他位置,并指示程序在特定位置查找插件。对于一次性动态导入,我是否可以这样做,而不是修改sys.path
?我不想污染这种全球性的。
相关:我可以依靠sys.path[0]
作为脚本的路径,即使它与当前工作目录(os.getcwd()
)不同吗?
__init__.py
);如果它导致问题,我可以简单地废弃它。
答案 0 :(得分:6)
这可能看起来很奇怪,但您可以修改模块的__path__
变量,然后从中导入。那你就不会搞乱sys.path中的全局导入空间。
编辑:如果在运行时加载目录,则不需要使用plugins.py文件来存储它们。您可以动态创建模块:
main.py:
#create the plugins module (pseudo-package)
import sys, os
sys.modules['plugins'] = plugins = type(sys)('plugins')
plugins.__path__ = []
for plugin_dir in ['plugins1', 'plugins2']:
path = os.path.join(sys.path[0], 'addons', plugin_dir)
plugins.__path__.append(path)
创建动态模块后,您可以像以前一样使用import_module
或__import__
加载插件:
from importlib import import_module
myplugins = []
for plugin in ['myplugin1', 'myplugin2']:
myplugins.append(import_module('plugins.' + plugin))
myplugins[-1].init()
##or using __import__:
myplugins = []
for plugin in ['myplugin1', 'myplugin2']:
myplugins.append(getattr(__import__('plugins.' + plugin), plugin))
myplugins[-1].init()
附加元件/ plugins1 / myplugin1.py:
def init():
print('myplugin1')
附加元件/ plugins2 / myplugin2.py:
def init():
print('myplugin2')
我从来没有使用过它,但它在Python 2& 3。