【问题标题】:Import file using string as name [duplicate]使用字符串作为名称导入文件[重复]
【发布时间】:2012-12-13 19:33:16
【问题描述】:

可能重复:
Dynamic module import in 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 为测试主模块执行并最终对其进行评估。

如您所见,我目前必须在顶部有一个导入列表。我不能简单地做 import testNametestName 的内容是我希望导入的模块的名称),因为它会尝试找到一个名为 testName 的模块,而不是一个名为 @ 的内容的模块987654334@.

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

我还要求我不要为使用 eval 而挂起、绘制或四分五裂,它用于一个非常受控的环境(它循环的列表在 .py 文件中,所以没有“结束用户”应该弄乱它)。

【问题讨论】:

  • 请注意,缩进在 ST 中是正确的,出于某种原因,我认为这个网站只是不喜欢正确解析我的文本:(
  • 不要使用制表符而是使用空格来缩进。
  • Python 已经有一种方法来管理您可能想要导入的大量 .py 文件集合,它可以理解文件夹和子文件夹,让您可以处理相对导入,正确地进行命名空间等等。它被称为package。你有什么不想使用的原因吗?

标签: python string import path


【解决方案1】:

不确定我是否理解正确,但您可以使用 __import__ 动态导入模块:

mod = __import__(testName)
mod.HelloWorld()

编辑:我不知道用户代码的 python 文档不鼓励使用 __import____import__ documentation(如 Bakuriu 所述)

This 也应该可以工作,并且会被认为是更好的风格:

import importlib

mod = importlib.import_module(testName)
mod.HelloWorld()

【讨论】:

  • 太棒了,非常感谢,花了一个多小时搜寻有关它的信息,我设法早点写出 __import__(testName) ,但没有意识到我必须将响应分配给一个模块或者我们,幸运的是我的所有函数都将在所有文件中命名为 Test,所以我可以从现在开始调用 mod.Test()。
  • @XtrmJosh 你看到其他答案了吗? __import__ 是一个实现细节;你应该使用importlib(或者imp,如果你不关心Python 3.x的兼容性)。
【解决方案2】:
  1. 如果您不知道自己在做什么,千万不要直接与 sys.modules 混淆。
  2. 有很多方法可以做你想做的事:
    1. 内置__import__函数
    2. 使用imp.load_module
    3. 使用importlib.import_module

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

【讨论】:

  • 这是import moduleName,其中moduleName 是字符串。 from moduleName import * 怎么样?
  • @NamGVU 尝试按上述方式导入模块,然后:globals().update(module.__dict__)
  • 像魅力一样工作。谢谢!
  • 我刚刚在这里找到了另一个解决方案,它只导入用户定义的变量stackoverflow.com/a/31306598/248616
【解决方案3】:

将模块所在的路径添加到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-05-24
    • 1970-01-01
    • 2011-07-13
    • 1970-01-01
    • 2015-01-12
    • 2021-02-05
    • 1970-01-01
    • 1970-01-01
    • 2015-07-26
    相关资源
    最近更新 更多