2013-05-08 62 views
2

我有以下目录结构的Python:导入文件基于哪些文件用户想要

+ code 
| 
--+ plugins 
    | 
    -- __init__.py 
    -- test_plugin.py (has a class TestPlugin) 
    -- another_test_plugin.py (has a class AnotherTestPlugin) 
--+ load.py 
--+ __init__.py 

在load.py,我希望能够仅初始化用户指定的类。例如,可以说我做类似

$ python load.py -c test_plugin # Should only import test_plugin.py and initialize an object of the TestPlugin class 

我无法尝试使用“imp”模块来执行此操作。它一直说“没有这样的文件或目录”。我的理解是,它不知道如何正确理解路径。有人可以帮我解决这个问题吗?

+0

你说你尝试使用'imp'模块时遇到问题,但是你到底尝试了哪些代码?你有什么麻烦?什么部分的教程/文档不了解? stackoverflow不是其他人为你写代码的地方! – zmo 2013-05-08 10:08:50

+0

你有看看http://stackoverflow.com/questions/10675054/how-to-import-the-module-in-python? – zmo 2013-05-08 10:10:14

+0

我正在尝试下面的代码 'import imp' 'import.load_source('TestPlugin','plugins/test_plugin.py')' – 2013-05-08 10:34:44

回答

-7
exec('import ' + sys.argv[2]) 
obj = test_plugin.TestPlugin() 

这里sys.argv [2]是来自命令行参数的'test_plugin'字符串。

编辑:另一种方法来避免使用EXEC:

import importlib 
mod = importlib.import_module(sys.argv[2]) 
+5

如果'sys.argv [2]'是'os; os.system(“邪恶命令”)'? – Bakuriu 2013-05-08 10:43:10

+1

'exec','eval'就像功能是邪恶的,永远不会被使用。 – zmo 2013-05-08 10:47:48

0

OK,你的问题是路径相关的问题。你期望脚本运行在load.py所在的目录下,而不是这种情况。

你必须做的是一样的东西:

import imp, os, plugins 

path = os.path.dirname(plugins.__file__) 
imp.load_source('TestPlugin', os.path.join(path, 'test_plugin.py') 

其中插件是包含所有插件模块(即刚好空__init__.py),这将有助于你得到的完整路径插件模块文件。

+0

谢谢,没有注意到我犯了这个错字:-) – zmo 2013-05-08 11:39:03

0

另一种解决办法,如果你想要一个“插件”搜索工具:

import imp, os 
import glob 

def load_plugins(path): 
    """ 
    Assuming `path` is the only directory in which you store your plugins, 
    and assuming each name follows the syntax: 
    plugin_file.py -> PluginFile 
    Please note that we don't import files starting with an underscore. 

    """ 
    plugins = {} 
    plugin_files = glob.glob(path + os.sep + r'[!_]*.py') 
    for plugin_path in plugin_files: 
    module_name, ext = os.path.splitext(plugin_path) 
    module_name = os.path.basename(module_name) 
    class_name = module_name.title().replace('_', '') 
    loaded_module = imp.load_source(class_name, plugin_path) # we import the plugin 
    plugins[module_name] = getattr(loaded_module, class_name) 
    return plugins 

plugins = load_plugins(your_path_here) 
plugin_name = sys.argv[3] 
plugin = plugins.get(plugin_name) 
if not plugin: 
    # manage a not existing plugin 
else: 
    plugin_instance = plugin() # creates an instance of your plugin 

这样,你也可以通过更改键指定不同的名称,例如,“test_plugins” =>“TP”。你不必初始化你的插件,但是当你想在运行时加载你的插件时,你仍然可以运行这个函数。

+0

如果用户编写了自己的插件并且想要加载它,该怎么办?主程序无法对其名称进行硬编码,因此插件的动态发现和*动态导入是必要的。 – Bakuriu 2013-05-08 11:44:27

+0

是的,这并不难。 – Markon 2013-05-08 12:49:40