This is due to the way Python handles the names of variables. In order to have some basis for the explanation, I extended your example with a list as a second imported variable:
mod1.py
count = 0
lst = [1, 2, 3]
def update_count():
global count
count = count + 1
def update_lst():
lst.append(4)
test.py
import mod1
from mod1 import count, lst, update_count, update_lst
print("mod1.count = ", mod1.count)
print("count = ", count)
print("mod1.lst = ", mod1.lst)
print("lst = ", lst)
update_count()
update_lst()
print('\nAfter updates: \n')
print("mod1.count = ", mod1.count)
print("count = ", count)
print("mod1.lst = ", mod1.lst)
print("lst = ", lst)
Output:
mod1.count = 0
count = 0
mod1.lst = [1, 2, 3]
lst = [1, 2, 3]
After updates:
mod1.count = 1
count = 0
mod1.lst = [1, 2, 3, 4]
lst = [1, 2, 3, 4]
So, what happened?
When you import count
and lst
, these new names are created in the namespace of your script. The name count
is another name for the integer object 0
already referred to by mod1.count
, and the name lst
is another name for the list already referred to by mod1.lst
.
When we execute the updates, the list gets updated in the module, but it remains the same object: mod1.lst
and lst
still refer to the same object.
Things are different for mod1.count
, as we make this name refer to a new object, the integer 1
, in count = count + 1
.
Now, mod1.count
refers to the integer object 1
, while count
in the main script still refers to the original 0
object.
So, that's all just normal Python names behaviour.
If you haven't read it yet, I recommend Ned Batchelder's classic Facts and myths about Python names and values that explains very well how names work in Python.