告诉__import__在哪里看 - 我是否坚持使用sys.path?

时间:2011-08-28 02:30:37

标签: python

我有一个纯Python的项目,带有一个基本的插件系统:你编写一个模块来定义一个具有特定接口和名称的类,程序导入模块,然后根据需要实例化该类。

目前,插件都来自特定文件夹(主.py文件所在的子目录)。我希望能够将它们放在磁盘上的其他位置,并指示程序在特定位置查找插件。对于一次性动态导入,我是否可以这样做,而不是修改sys.path?我不想污染这种全球性的。

相关:我可以依靠sys.path[0]作为脚本的路径,即使它与当前工作目录(os.getcwd())不同吗?

编辑:我忘了提及 - 我希望能够从几个不同的文件夹中获取插件,用户可以指定插件文件夹的路径。目前,每个文件夹都设置为一个包(带有__init__.py);如果它导致问题,我可以简单地废弃它。

1 个答案:

答案 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。