Python 使用字符串作为名称导入文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14071135/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 10:21:56  来源:igfitidea点击:

Import file using string as name

pythonstringimportpath

提问by XtrmJosh

Possible Duplicate:
Dynamic module import in Python

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

I intend to make a suite of files at some point soon, and the best way to organize it is to have a list, that list will be at the very top of a file, and after it will come a ridiculous amount of code to handle what that list controls and how it operates. I'm looking to write said list only once, and said list is a list of folder and file names in this format:

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

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

As you can see, folder/filenameare the same (sort of). File name is folder name with .pyon the end, but doing import XXX you don't need to do import XXX.py, so I don't see this causing an issue.

如您所见,folder/filename是相同的(有点)。文件名是.py末尾带有的文件夹名,但是执行 import XXX 您不需要执行 import XXX.py,所以我不认为这会导致问题。

The problem I'm facing is importing using this method...

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

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)

So for each test I have, print the name, assemble a string which contains the path ("\\testName"), for this example, print the test path, then add the path to the list (sys.path.append(path)), then print to confirm it happened, then assemble a string which will be executed by evalfor the tests main module and eventually eval it.

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

As you can see, I'm currently having to have a list of imports at the top. I can't simply do import testName(the contents of testNameare the name of the module I wish to import), as it will try to find a module called testName, not a module called the contents of testName.

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

I've seen a few examples of where this has been done, but can't find any which work in my circumstances. If someone could literally throw a chunk of code which does it that would be wonderful.

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

I'd also request that I'm not hung, drawn, nor quartered for use of eval, it is used in a very controlled environment (the list through which it cycles is within the .py file, so no "end user" should mess with it).

我还要求我没有被挂起、绘制或分割使用 eval,它是在一个非常受控的环境中使用的(它循环的列表在 .py 文件中,所以没有“最终用户”应该惹它)。

采纳答案by lbonn

Not sure if I understood everything correctly, but you can import a module dynamically using __import__:

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

mod = __import__(testName)
mod.HelloWorld()

Edit: I wasn't aware that the use of __import__was discouraged by the python docs for user code: __import__ documentation(as noted by Bakuriu)

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

Thisshould also work and would be considered better style:

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

import importlib

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

回答by Bakuriu

  1. Never, ever, ever mess with sys.modulesdirectly if you don't know exactly what you are doing.
  2. There are a lot of ways to do what you want:
    1. The build-in __import__function
    2. Using imp.load_module
    3. Using importlib.import_module
  1. sys.modules如果您不确切地知道自己在做什么,则永远不要直接搞砸。
  2. 有很多方法可以做你想做的事:
    1. 内置__import__函数
    2. 使用 imp.load_module
    3. 使用 importlib.import_module

I'd avoid using __import__directly, and go for importlib.import_module(which is also suggested at the end of the documentation of __import__).

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

回答by Swapnil

Add the path where module resides to sys.path. Import the module using __import__ function which accepts a string variable as module name.

将模块所在的路径添加到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