Concept of namespace, global, local with respect to import

Question:

I understand that below are the scoping levels in python (listed in highest to lowest order)

  • Local(L): Defined inside function/class
  • Enclosed(E): Defined inside enclosing functions(Nested function concept)
  • Global(G): Defined at the uppermost level
  • Built-in(B): Reserved names in Python builtin modules

I understand this concept when we have a single file. I am trying to understand how this concept of namespace, local, enclosed, global, built-in works when using import in python.

I understand we can import using foll. approaches:

  1. import modulename
  2. import modulename.function(function/variable)
  3. import package.module.function(function/variable)
  4. from module import function(function/variable)
  5. from package import module
  6. from package.module import function(function/variable)
  7. from module import *
  8. from package import *

I know that in each of the above the entire module is loaded in the sys modules dictionary. But I am confused with respect to namespace, scope, global, local. I want to understand LEGB principle, namespace, global, localwith respect to the method of import vs from import. I have read that in case of point 1 (import modulename), the modulename is loaded in its own namespace and reference is available to the calling module with which it can change the variable values globally. Does this also mean it is in global namespace? Any if so then global with respect to what? Also I have read that from module import function/variable or from module import * brings function(s)/variable(s) in the calling modules namespace and any changes are not global. Does this mean that it is in local namespace? Local with respect to what?

Example:
Say module foo has a variable bar=10. When we use [import foo] – this brings foo in current namespace and allows us to change the value of bar via foo.bar=1000 and this change is visible to every piece of code that makes use of [import foo print(foo.bar)] after the above assignment was made. Where as in case of [from foo import bar], any change made to bar is only visible to this module and not any other module irrespective of whether they do an [import foo] or [from foo import bar] they would see value of bar as 10.

Any reference/links in this area will be very helpful. I want to understand the basics of how this works internally. Any information will be helpful to understand this. Articles that I found on this topic explain what is import vs from xx import yy. But they don’t explain why/how the changes made become global (in case of import) vs local (in case of from import).

Some more examples:
In below code example, change made to a is only seen in the main.py file and does not affect the value of a in module1.py and subsequent modules that import module1.py will still see the value of a as 10.

module1.py:

a=10

main.py:

from module1 import a
print(a)
a=100

Whereas if we used import module1 instead of from module1 import a then the assignment would have changed value of a in module1.py and any subsequent import of module1.py would show the value of a as 100.

Note: Similarly we could also have functions inside the module.py that get and set the value of variable a. And using this approach, once we do a from module1 import getfn, setfn in main.py, we can use these functions which when called make the change to variable a and this change is globally visible.

Asked By: variable

||

Answers:

You’re over complicating things. From the point of view of imports, the only thing to know is that import foo brings foo into the current namespace, and from foo import bar brings bar into the current namespace.

Answered By: Daniel Roseman

Python has only 3 scopes: global local and builtin.
They are relative to the position in the code

Every variable whose value you can change is local
(note that changing global variable results in creating a new local variable instead,
so there are local and global variable of the same name)
Enclosed you speak of are local to that function

Every variable with unchangeable content whose value you can get is global

Builtin variables are exactly like global so they can even be considered global

to see what variables are global and what are local, put this line in your code
print("global:", globals(), "nnlocal:", locals())

Answered By: Superior