Why can't you re-import Python?

There are many questions and answers regarding re-importing to SO, but it all seems very controversial, not knowing the mechanisms behind it.

If you import a module, change its contents, try to import it again, you will find that the second import has no effect:

>>> import foo # foo.py contains: bar = 'original' >>> print foo.bar original >>> # edit foo.py and change to: bar = 'changed' >>> import foo >>> print foo.bar original 

I was a very happy tourist when I discovered reload :

 >>> reload(foo) >>> print foo.bar changed 

However, there is no simple solution when importing elements from a module without importing the module itself:

 >>> from foo import baz >>> print baz original >>> # change foo.py from baz = 'original' to baz = 'changed' >>> from foo import baz >>> print baz original >>> reload(foo) Traceback (most recent call last): File "<pyshell#10>", line 1, in <module> reload(foo) NameError: name 'foo' is not defined 

Why doesn't Python update imported elements when you give it a new import statement?

+3
source share
2 answers

When a module is imported, it is cached in sys.modules . Any attempt to import the same module again into the same session simply returns the existing module contained there. This speeds up the overall experience when a module is imported from multiple locations. It also allows the module to have its own objects shared between all imports, since the same module is returned every time.

As already mentioned, you can use reload to re-import the whole module. Check the documentation for warnings because even this is not flawless.

When importing certain elements from a module, the entire module is imported as described above, and then the requested objects are placed in your namespace. reload does not work because these objects are not modules, and you never received a link to the module itself. The workaround is to get a link to the module, reload it, and then re-import:

 >>> from foo import baz >>> print baz original >>> # change foo.py from baz = 'original' to baz = 'changed' >>> import foo >>> reload(foo) >>> from foo import baz >>> print baz changed 
+10
source

A simple explanation of why is that import statements include two operations: loading a module (i.e., running code inside it) and importing names into the namespace of the import module. Re-import only repeats the second operation. The reason is that the first operation can be costly in terms of computing and memory resources.

reload provided as a way to repeat the first operation, but as you have seen, this requires a module name. However, do not be fooled into thinking that from foo import bar does not load the entire module. It does. All module code is running, you can just look at the names (for example, bar ) that you explicitly import. For this reason, there is a slight difference between importing a module, rather than importing; the only differences are namespace problems. Therefore, if you think you can reload the foo module, you should go ahead and make import foo . If you want, you can do this to update the imported names:

 import foo from foo import bar # later... reload(foo) from foo import bar 

There is another reason you cannot reimport individual names, which means that Python has no way to change the objects referenced; he can only rename names. Suppose you did this:

 from foo import bar newBar = bar from foo import bar 

Even if the second import really updated the value of bar, it will never be able to update the value of newBar, because neither foo nor bar have any way of knowing that you created an additional name to refer to bar. Avoiding rewriting individual names prevents you from falling into this trap; if people thought that re-importing would update names, it would be easy to forget that it would not update objects anyway.

+2
source

All Articles