What Happens When a Module Is Imported Twice

What happens when a module is imported twice?

Nothing, if a module has already been imported, it's not loaded again.

You will simply get a reference to the module that has already been imported (it will come from sys.modules).

To get a list of the modules that have already been imported, you can look up sys.modules.keys() (note that urllibhere imports a lot of other modules):

>>> import sys
>>> print len(sys.modules.keys())
44
>>> print sys.modules.keys()
['copy_reg', 'sre_compile', '_sre', 'encodings', 'site', '__builtin__', 'sysconfig', '__main__', 'encodings.encodings', 'abc', 'posixpath', '_weakrefset', 'errno', 'encodings.codecs', 'sre_constants', 're', '_abcoll', 'types', '_codecs', 'encodings.__builtin__', '_warnings', 'genericpath', 'stat', 'zipimport', '_sysconfigdata', 'warnings', 'UserDict', 'encodings.utf_8', 'sys', 'virtualenvwrapper', '_osx_support', 'codecs', 'readline', 'os.path', 'sitecustomize', 'signal', 'traceback', 'linecache', 'posix', 'encodings.aliases', 'exceptions', 'sre_parse', 'os', '_weakref']
>>> import urllib
>>> print len(sys.modules.keys())
70
>>> print sys.modules.keys()
['cStringIO', 'heapq', 'base64', 'copy_reg', 'sre_compile', '_collections', '_sre', 'functools', 'encodings', 'site', '__builtin__', 'sysconfig', 'thread', '_ssl', '__main__', 'operator', 'encodings.encodings', '_heapq', 'abc', 'posixpath', '_weakrefset', 'errno', '_socket', 'binascii', 'encodings.codecs', 'urllib', 'sre_constants', 're', '_abcoll', 'collections', 'types', '_codecs', 'encodings.__builtin__', '_struct', '_warnings', '_scproxy', 'genericpath', 'stat', 'zipimport', '_sysconfigdata', 'string', 'warnings', 'UserDict', 'struct', 'encodings.utf_8', 'textwrap', 'sys', 'ssl', 'virtualenvwrapper', '_osx_support', 'codecs', 'readline', 'os.path', 'strop', '_functools', 'sitecustomize', 'socket', 'keyword', 'signal', 'traceback', 'urlparse', 'linecache', 'itertools', 'posix', 'encodings.aliases', 'time', 'exceptions', 'sre_parse', 'os', '_weakref']
>>> import urllib #again!
>>> print len(sys.modules.keys()) #has not loaded any additional modules
70

Let's give it a whirl:

import sys
>>> sys.modules["foo"] = "bar" # Let's pretend we imported a module named "foo", which is a string.
>>> print __import__("foo")
bar # Not a module, that's my string!

As you can see, if a module is found un sys.modules, you'll just get a new reference to it. That's it.


Note that this means that modules should be designed so as to not have side effects (such as printing stuff) when they're imported.

Reloading modules, outside of an interactive session, is usually not a very good practice either (although it has its use cases) - the other answers will detail how you'd do this.

What could cause a python module to be imported twice?

A Python module can be imported twice if the module is found twice in the path. For example, say your project is laid out like so:

  • src/
    • package1/
      • spam.py
      • eggs.py

Suppose your PYTHONPATH (sys.path) includes src and src/package1:

PYTHONPATH=/path/to/src:/path/to/src/package1

If that's the case, you can import the same module twice like this:

from package1 import spam
import spam

And Python will think they are different modules. Is that what's going on?

Also, per the discussion below (for users searching this question), another way a module can be imported twice is if there is an exception midway through the first import. For example, if spam imports eggs, but importing eggs results in an exception inside the module, it can be imported again.

Do python modules get imported twice?

When you do import math it is imported and put into sys.modules. Next you do import math it is checked if math is in sys.modules and fetched from there.

So it is imported only once.

http://effbot.org/zone/import-confusion.htm

When Python imports a module, it first checks the module registry
(sys.modules) to see if the module is already imported. If that’s the
case, Python uses the existing module object as is.

Otherwise, Python does something like this:

  1. Create a new, empty module object (this is essentially a dictionary)
  2. Insert that module object in the sys.modules dictionary
  3. Load the module code object (if necessary, compile the module first)
  4. Execute the module code object in the new module’s namespace. All variables assigned by the code will be available via the module object.

This
means that it’s fairly cheap to import an already imported module;
Python just has to look the module name up in a dictionary.

How to prevent a module from being imported twice?

Python modules aren't imported multiple times. Just running import two times will not reload the module. If you want it to be reloaded, you have to use the reload statement. Here's a demo

foo.py is a module with the single line

print("I am being imported")

And here is a screen transcript of multiple import attempts.

   >>> import foo
Hello, I am being imported
>>> import foo # Will not print the statement
>>> reload(foo) # Will print it again
Hello, I am being imported

Will the library be imported twice?

No, once it's loaded, it's cached and won't be loaded again. You can safely import it into any source file where you need it to be in scope without performance hit.

Note that this is also relevant if you realise that when a module is first loaded, it is actually executed.

For example if you have my_mod.py:

def hello():
print('hello')

print('loading')

And you use it from main.py:

import my_mod

input('waiting, press enter')
hello()

You'll notice that loading will be printed and then after you enter something hello gets printed. You can import the same file again from other modules, but loading won't be printed again, since the module doesn't get executed again, it just gets brought into scope for wherever you import it.

Python: How to load a module twice?

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

Importing the same module twice because of the Shared Service

The above approach should work fine. There won't be any issues in doing as above.

Once your app.module.ts configured with ngx-translate you can implement on other modules using shared.module as mentioned in ngx-translate repository, then you don’t need to worry about importing TranslateModule everytime. You only need to add this in your shared.module:

Read more on this.

ES6 Do importing same component multiple times across an SPA have performance issues?

This is working because it is based on nodejs require and is something you can do just because you are compiling your js. During compilation every module/component will get it's own IIFE and import means components are simply injected into other modules/components. There won't be any performance issues if you use vue cli or webpack, since every module will only be included one time in the final compiled code.



Related Topics



Leave a reply



Submit