77

Possible Duplicate:
Dynamic module import in Python

I am writing a small script that gets the name of a file from a directory and passes this to another module which then imports the file.

so the flow is like 1) get module name ( store it in a variable) 2) pass this variable name to a module 3) import the module whose name is stored in the variable name

my code is like

data_files = [x[2] for x in os.walk(os.path.dirname(sys.argv[0]))]
hello = data_files[0]
modulename = hello[0].split(".")[0]

import modulename

the problem is when it reaches the import statement, it reads modulename as a real module name and not the value stored in this variable. I am unsure about how this works in python, any help on solving this problem would be great

Amin.MasterkinG
  • 789
  • 1
  • 12
  • 23
user1801279
  • 1,573
  • 5
  • 23
  • 39

2 Answers2

68

You want the built in __import__ function

new_module = __import__(modulename)
mgilson
  • 283,004
  • 58
  • 591
  • 667
  • 4
    After the code you've written runs, what is stored in `new_module`? Is it how I now refer to `modulename`, the same way that `np` refers to `numpy` after running `import numpy as np`? – NeutronStar Dec 31 '14 at 18:21
  • I have the same question. Suppose new_module is a package (in folder modulename) and it has file foo.py inside. I don't think you can call new_module.foo.somefunction(), it will say there is no module foo. – Marc Oct 14 '15 at 18:50
  • 6
    IIRC, I believe that `foo = __import__('foo')` should be equivalent to `import foo`. `bar = `__import__('foo')` is the same as `import foo as bar`, etc. If you're working with a package, the package's `__init__.py` will be imported as per usual. e.g. `__import__('numpy').core` gives you the numpy core subpackage since numpy's `__init__.py` imports `numpy.core`. – mgilson Oct 14 '15 at 18:53
  • When I imported a submodule, I still needed to access it with the full path - so it wasn't good enough for me. E.g. m = __import__("a.b.c"), and then I'd need to reference c as m.b.c. – jciloa Sep 05 '19 at 06:50
45

importlib is probably the way to go. The documentation on it is here. It's generally preferred over __import__ for most uses.

In your case, you would use:

import importlib
module = importlib.import_module(module_name, package=None)
mgilson
  • 283,004
  • 58
  • 591
  • 667
munk
  • 11,550
  • 7
  • 49
  • 70
  • 4
    Use [`imp.load_source(..)` from the `imp` module](https://docs.python.org/2/library/imp.html#imp.load_source) if you don't know the path to the module `.py` file. – Evgeni Sergeev Jun 08 '14 at 06:34
  • How do I do a `from` import with multiple selections with this. Like `from configparser import ConfigParser, NoSectionError`? And `from foo import *`? – 576i Feb 19 '17 at 19:34
  • @576i if you've imported configparser as module, you can provide the names with `ConfigParser = configparser.ConfigParser` and so on. `import *` is mischief and I won't encourage it. – munk Feb 20 '17 at 20:58