91

I have some code 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 goal is to get the name of a file from a directory as a string, pass it to some other code, and then import the module whose name is stored in the variable name.

However, in my code attempt, the modulename in import modulename is treated as the name of the module to import, rather than the string stored in that variable.

How can I get the effect that I want instead?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
user1801279
  • 1,743
  • 5
  • 24
  • 40

2 Answers2

82

You want the built in __import__ function

new_module = __import__(modulename)
mgilson
  • 300,191
  • 65
  • 633
  • 696
  • 5
    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
  • 7
    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
  • 1
    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
48

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
  • 300,191
  • 65
  • 633
  • 696
munk
  • 12,340
  • 8
  • 51
  • 71
  • 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
  • 2
    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
  • 1
    @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