global a refers to the name a in the glbltest module's namespace. When you set a by hand, it refers to the name a in the __main__ module's namespace.
When you use from glbltest import * the names in the module are imported into the __main__ module's namespace. Those are different names but refer to the same objects. When you use global a and a = [20,30,40] in the glbltest module, assignment makes a new object that a in glbltest module's namespace now refers to. The name a in the __main__ module still refers to the original object (the empty list).
As a simple example, print the id() of a in the fun() function, and print(id(a)) "by hand" after you set it:
a = [] def fun(): global a print(a, id(a)) a = [20,30,40] print(a, id(a)) # To view the global a object id again def show(): print(a, id(a))
"by hand", with comments:
>>> from glbltest import * >>> a # the imported name [] >>> id(a) # its object ID 2056911113280 >>> fun() [] 2056911113280 # start of fun() the object is the same ID [20, 30, 40] 2056902829312 # but assignment changes to new object (different ID) >>> a [] # main a still refers to original object >>> id(a) 2056911113280 >>> show() # glbltest module still sees *its* global a [20, 30, 40] 2056902829312
Note that if you use mutation vs. assignment to change the existing object. You'll see the change:
a = [] def fun(): global a print(a, id(a)) a.extend([20,30,40]) # modify existing object, not assigning a new object. print(a, id(a)) # To view the global a object id again def show(): print(a, id(a))
Now the object IDs remain the same.
>>> from glbltest import * >>> a, id(a) # import object ([], 1408887112064) >>> fun() [] 1408887112064 # before change still the same object [20, 30, 40] 1408887112064 # mutated the *existing* list >>> a, id(a) ([20, 30, 40], 1408887112064) # main's 'a' refers to the same object, same ID >>> show() [20, 30, 40] 1408887112064 # glbltest refers to the same object, same ID
It's a bit more obvious that the names are different if you just import the module and the module's a can be referred to directly as glbltest.a.
a = [] def fun(): global a a = [20,30,40]
>>> import glbltest >>> glbltest.a [] >>> a = 5 # main's a >>> a 5 >>> glbltest.a # module's a [] >>> glbltest.fun() >>> a # main's a doesn't change 5 >>> glbltest.a # module's a does. [20, 30, 40]