8

Is there a way to load a module twice in the same python session?
To fill this question with an example: Here is a module:

Mod.py

x = 0

Now I would like to import that module twice, like creating two instances of a class to have actually two copies of x.

To already answer the questions in the comments, "why anyone would want to do that if they could just create a class with x as a variable":
You are correct, but there exists some huge amount of source that would have to be rewritten, and loading a module twice would be a quick fix^^.

Woltan
  • 13,723
  • 15
  • 78
  • 104

3 Answers3

19

Yes, you can load a module twice:

import mod
import sys
del sys.modules["mod"]
import mod as mod2

Now, mod and mod2 are two instances of the same module.

That said, I doubt this is ever useful. Use classes instead -- eventually it will be less work.

Edit: In Python 2.x, you can also use the following code to "manually" import a module:

import imp

def my_import(name):
    file, pathname, description = imp.find_module(name)
    code = compile(file.read(), pathname, "exec", dont_inherit=True)
    file.close()
    module = imp.new_module(name)
    exec code in module.__dict__
    return module

This solution might be more flexible than the first one. You no longer have to "fight" the import mechanism since you are (partly) rolling your own one. (Note that this implementation doesn't set the __file__, __path__ and __package__ attributes of the module -- if these are needed, just add code to set them.)

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • Hi Sven, thank you for your answer. It works :) And I couldn't agree more, that using classes is a better solution (if loading a module twice can be considered as a solution). But for now, this will have to do. Just imagine a poor written package with **a** **lot** of modules where there are "static" variables all over the place. Loading a module twice is a work around until someone is forced to rewrite the package, either because it is not maintainable any longer or everything collapses ;) – Woltan Jun 28 '11 at 14:37
  • @Woltan: Are you using Python 2.x or 3.x? There are other ways to do this, which might be more convenient depending on context, but they will work differently in different versions of Python. – Sven Marnach Jun 28 '11 at 14:47
  • I am working with Python 2.7. What other possibilities are there? – Woltan Jun 28 '11 at 14:49
  • @Woltan: I added an alternative mechanism which may provide more control since you can adapt it to your needs. – Sven Marnach Jun 28 '11 at 15:09
4

Deleting an entry from sys.modules will not necessarily work (e.g. it will fail when importing recurly twice, if you want to work with multiple recurly accounts in the same app etc.)

Another way to accomplish this is:

>>> import importlib
>>> spec = importlib.util.find_spec(module_name)
>>> instance_one = importlib.util.module_from_spec(spec)
>>> instance_two = importlib.util.module_from_spec(spec)
>>> instance_one == instance_two
False
Janis Kirsteins
  • 2,128
  • 16
  • 17
-1

You could use the __import__ function.

module1 = __import__("module")
module2 = __import__("module")

Edit: As it turns out, this does not import two separate versions of the module, instead module1 and module2 will point to the same object, as pointed out by Sven.

Håvard
  • 9,900
  • 1
  • 41
  • 46
  • 5
    This does not work -- `module1 is module2` will prove they end up being the same object. – Sven Marnach Jun 28 '11 at 14:20
  • __import__() is one way to do this, but it's not generally recommended, and for good reason--you really shouldn't be loading a module twice. I don't see why `import module` and then `import module as mod` wouldn't work, though. If they want more than than just having two references to the same module, neither work. – Dylnuge Jun 28 '11 at 14:25
  • @Dylnuge Here's an example: suppose a module loads a TensorFlow model at import time (and this maps some GPU memory and sets of a TensorFlow graph). You can't reload the module, because it will cause errors with TensorFlow conflicting with the graph variables and memory it mapped on the first import, which is not solved by deleting the module either (these things are outside of Python). Suppose in a unit test you want to test import behavior, like selectively loading different models based on `os.environ` variables. You want to import the same module, but with a patch of `os.environ`. – ely Aug 29 '17 at 14:56