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]