One sentence rule: the reference of a variable is visible to all its lower levels, thus mutable variables are visible and able to be modified in the lower levels, immutable variables are visible in the lower levels, but not able to be modified since the modification will create a local variable instead of modify the variable in the upper levels
n = 10; #global variables def f(): m = 100; print(dir()) # ['m'] print(globals()) # {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x108df2860>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 's1.py', '__cached__': None, 'n': 10, 'f': <function f at 0x108cf52f0>} print(locals()) # {'m': 100} print(dir()) # ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'f', 'n'] f();
n = 10 # global variable print(id(n), n) # 4405450128 10 # access local variable def f1(): n = 1; print(id(n), n) # 4450449840 1, reference local variable n # access variable in enclosing function def f2(): n = 2; def f3(): print(id(n), n) # 4405449872 2, reference n defined in f2 f3(); # access global variable def f4(): def f5(): print(id(n), n) # 4405450128 10, reference global variable f5(); f1(); f2(); f4();
a = 10 # global variable print(id(a), a) # 27193472, 10 def f1(): # global variable is visible to the lower level # globals: {'a': 10, ...} print(id(a), a) # 27193472, 10 def f2(): # create a local variable, which screens the global variable # globals: {'a': 10, ...} a = 100 # locals: {'a': 100} print(id(a), a) # 27195296 100 f1() f2() print(id(a), a) # 27193472, 10
l = list(range(10)) # global variable print(id(l), l) # 140678046472600, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] def f3(): # the reference of the gocal variable is visible to the lower level print(id(l), l) # 140678046472600, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] def f4(): # modify an element of the global variable l[1] = 100 print(id(l), l) # 140678046472600, [0, 100, 2, 3, 4, 5, 6, 7, 8, 9] f3() f4() print(id(l), l) # 140678046472600, [0, 100, 2, 3, 4, 5, 6, 7, 8, 9] def f5(): # create a local variable, which screens the global variable l = [1, 2, 3, 4] print(id(l), l) # 139718240373432, [1, 2, 3, 4] f5() print(id(l), l) # 140678046472600, [0, 100, 2, 3, 4, 5, 6, 7, 8, 9]
t = 10 print(id(t), t) # 140417416870688, 10 def f8(): global t # t is a global variable print(id(t), t) #140417416870688, 10 t = 100 # modify the global variable t, create a new address, reference global variable to new address print(id(t), t) #140249594380832, 100 print('globals: ', globals()) # globals: {'t': 100} print('locals: ', locals()) # locals: {} f8() print(id(t), t) # 140249594380832, 100
def f(): import math; # import math in local namespace print(math.pi) f(); #print(math.pi) # not import math error
# g.py global_list = [1, 2] print('g', id(global_list), global_list)
# a.py print('a ...') #import g from g import global_list def change(): global_list.append(100) change() print('a', id(global_list), global_list)
# b.py print('b ...') #import g from g import global_list from a import * def display(): print('display', id(global_list), global_list) print('b', id(global_list), global_list) change() display()
# python b.py b ... # start module b g 140597500568384 [1, 2] # import module g a ... # import module a a 140597500568384 [1, 2, 100] # global_list in a b 140597500568384 [1, 2, 100, 100] # global_list in b
# g.py global_list = [1, 2]
# a.py print('a ...') from g import global_list print('a', id(global_list), global_list)
# b.py print('b ...') from a import * print('b', id(global_list), global_list) # global_list is available in b.py