I have had a problem with the difference between import module and from module import name1, name2 ... in Python. I am a newcomer (last week) to Python, using Python 3.6 on Windows-64.
In the Python Tutorial there is a short discussion of these two import approaches. It is stated that from module import * is not recommended because of the danger of polluting the current namespace. However, there is no indication that there is any material operational difference between import module and from module import name1, name2.., with the implication that this is a matter of preference or convenience.
However, there seems to be a big difference in practice. Consider this module named ModuleA, defining a global variable and a function:
# ModuleA
iGlobalA = 0
def fA():
iGlobalA += 1
print( "MA: iGlobalA=", iGlobalA )
print( "Module A Initialised, iGlobalA=", iGlobalA )
Using import ModuleA creates a separate ModuleA namespace. Now the members of that module are available as public members of the namespace, like this:
import ModuleA as MA
def fX():
print( "MX: Before, ModuleA.iGlobalA=", MA.iGlobalA )
MA.fA()
print( "MX: After 1, ModuleA.iGlobalA=", MA.iGlobalA )
MA.fA()
print( "MX: After 2, ModuleA.iGlobalA=", MA.iGlobalA )
fX()
This is the output:
MA: Initialised, iGlobalA= 100
MX: Before, ModuleA.iGlobalA= 100
MA: iGlobalA incremented to 101
MX: After 1, ModuleA.iGlobalA= 101
MA: iGlobalA incremented to 102
MX: After 2, ModuleA.iGlobalA= 102
which is exactly as expected. Contrast this with ModuleY which uses the form from ModuleA import fA, iGlobalA and then refers to these members of ModuleA without qualification:
# ModuleY
from ModuleA import fA, iGlobalA
def fY():
print( "MY: Before, ModuleA.iGlobalA=", iGlobalA )
fA()
print( "MY: After 1, ModuleA.iGlobalA=", iGlobalA )
fA()
print( "MY: After 2, ModuleA.iGlobalA=", iGlobalA )
fY()
In this case the output is:
MA: Initialised, iGlobalA= 100
MY: Before, ModuleA.iGlobalA= 100
MA: iGlobalA incremented to 101
MY: After 1, ModuleA.iGlobalA= 100
MA: iGlobalA incremented to 102
MY: After 2, ModuleA.iGlobalA= 100
In this case the global variable iGlobalA is imported as a copy from ModuleA after ModuleA is initialised, and becomes a completely separate variable from ModuleA.iGlobalA. It is also true that function fA is imported as a reference to the function in ModuleA as defined at the time of import - if the function is reassigned at some later point within ModuleA, then the reference to fA() in the importing module remains unchanged, pointing only to the function as originally imported.
I would have thought these differences between these import syntaxes should be more clearly stated in the documentation. It also means that someone designing a library module needs to specify how that module should be imported.
Edit - after comment by @abdullah-ahmed-ghaznavi These are my questions
- Did I miss something in the documentation?
- Is this behaviour the same across all platforms?
- Is this the intended behaviour that can be relied upon in future?
import moduleorfrom module import whatever.from module mod import funcor whatever, that is equivalent toimport mod; func = mod.func; del mod. The rest of the behavior you are seeing stems from the documented semantics of Python assignment. You can read a good summary here