33

Possible Duplicate:
Dynamic module import in 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/filename are the same (sort of). File name is folder name with .py on the end, but doing import XXX you don't need to do import XXX.py, so I don't see this causing an issue.

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 eval for the tests main module and eventually eval it.

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 testName are 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.

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).

4
  • Note that the indentation is correct in ST, for some reason I think this website just doesn't like parsing my text correctly :( Commented Dec 28, 2012 at 14:39
  • 1
    Don't use tabs but spaces for indentation. Commented Dec 28, 2012 at 14:41
  • 2
    Python already has a way of managing large collections of .py files that you might want to import, which understands folders and subfolders, lets you handle relative imports, does namespacing properly, and so on. It's called a package. Is there a reason you don't want to use one? Commented Dec 28, 2012 at 14:50
  • duplicate also of: stackoverflow.com/questions/8718885/… Commented Jun 23, 2015 at 16:23

3 Answers 3

74

Not sure if I understood everything correctly, but you can import a module dynamically using __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)

This should also work and would be considered better style:

import importlib

mod = importlib.import_module(testName)
mod.HelloWorld()
Sign up to request clarification or add additional context in comments.

4 Comments

Marvelous, thanks a ton for this, spent well over an hour scouring for information on it, I managed to write out __import__(testName) earlier, but didn't realise I had to assign the response to a module or w.e, fortunately all my functions will be named Test throughout all files, so I can just call mod.Test() from now on.
@XtrmJosh have you seen the other answer? __import__ is an implementation detail; you should use importlib (or imp if you don't care about Python 3.x compatibility).
What kind of values are allowed for testName? Do I put .py at the end? Do I provide a relative path or an absolute path?
Aaron lead me to the solution to my problem. I added .py to testName. This does not work. Use your file name without extension!
24
  1. Never, ever, ever mess with sys.modules directly 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

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

4 Comments

This is for import moduleName where moduleName is string. How about from moduleName import * ?
@NamGVU try to import the module as above and then: globals().update(module.__dict__)
I just found another solution here which import only the user-defined variables stackoverflow.com/a/31306598/248616
Where can I find examples of how to do this? I want to run methods defined in Python scripts in subfolders. Do I provide a relative path? Absolute path? Do I put a .py suffix?
3

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

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.