23

可能重复:
Python 中的动态模块导入

我打算在不久的将来制作一套文件,组织它的最好方法是有一个列表,该列表将位于文件的最顶部,然后会出现大量可笑的代码来处理该列表控制什么以及它如何运作。我希望只写一次所说的列表,并且所说的列表是这种格式的文件夹和文件名列表:

[(folder/filename, bool, bool, int), (folder/filename, bool, bool, int)]

正如你所看到的,folder/filename都是一样的(有点)。文件名是.py最后的文件夹名称,但是导入 XXX 你不需要导入 XXX.py,所以我认为这不会导致问题。

我面临的问题是使用这种方法导入......

for (testName, auto, hardware, bit) in testList:
    print(testName)
    paths = "\\" + testName
    print paths
    addpath(paths)
    sys.modules[testName] = testName # One of a few options I've seen suggested on the net
    print("Path Added")
    test = testName + ".Helloworld()"
    eval(test)

因此,对于我拥有的每个测试,打印名称,组装一个包含路径 ( "\\testName") 的字符串,对于本示例,打印测试路径,然后将路径添加到列表 ( sys.path.append(path)),然后打印以确认它发生了,然后组装一个将由eval测试主模块执行并最终评估它的字符串。

如您所见,我目前必须在顶部有一个进口清单。我不能简单地进行导入testName(的内容testName是我希望导入的模块的名称),因为它会尝试找到一个名为 的模块testName,而不是一个名为 的内容的模块testName

我已经看到了一些这样做的例子,但在我的情况下找不到任何工作。如果有人可以从字面上抛出一大块代码,那就太好了。

我还要求我不要挂,画,也不要为了使用 eval 而四分五裂,它是在一个非常受控的环境中使用的(它循环的列表在 .py 文件中,所以没有“最终用户”应该弄乱它)。

4

3 回答 3

56

不确定我是否正确理解了所有内容,但您可以使用以下方法动态导入模块__import__

mod = __import__(testName)
mod.HelloWorld()

编辑:我不知道__import__python 文档不鼓励使用用户代码:__import__ 文档(如 Bakuriu 所述)

也应该有效,并且会被认为是更好的风格:

import importlib

mod = importlib.import_module(testName)
mod.HelloWorld()
于 2012-12-28T14:45:20.267 回答
22
  1. sys.modules如果你不知道自己在做什么,就永远不要直接搞砸。
  2. 有很多方法可以做你想做的事:
    1. 内置__import__函数
    2. 使用imp.load_module
    3. 使用importlib.import_module

我会避免__import__直接使用,而是选择importlib.import_module(在文档末尾也建议__import__)。

于 2012-12-28T14:47:01.827 回答
2

将模块所在的路径添加到 sys.path 中。使用 __import__ 函数导入模块,该函数接受字符串变量作为模块名称。

import sys
sys.path.insert(0, mypath)  # mypath = path of module to be imported
imported_module = __import__("string_module_name") # __import__ accepts string 
imported_module.myfunction()   # All symbols in mymodule are now available normally
于 2012-12-28T14:55:42.590 回答