I have a file A with 2 global variables
root = ""
crumbs = 
global root, crumbs
line = line.strip()
open_tag = is_valid_open(line)
kv = get_kv(line)
if open_tag is not None:
root += open_tag + "."
print root <---------- prints stuff
elif kv is not None:
crumbs.append(kv + "=" + kv)
print crumbs <---------- prints stuff
from A import read, root, crumbs
print "." + root + "." <---------- prints NOTHING
print "." + str(crumbs) + "." <---------- prints stuff
In short, it's because
+= does different things for lists and strings.
Strings are immutable. Therefore,
root += ... in your A.py creates a new string and assigns it to
root. There were two references to
root: one in A.py and one in your test script. The
root += line changes only
root in A.py since that's the only one that a function in A.py has access to. The
root in your test module is not changed.
Lists are mutable. Therefore,
crumbs += modifies the existing list, and doesn't change what
crumbs points to. Since
crumbs still refers to the same list in both A.py and in your test module, you see the change in your test module.
It becomes clearer if you write these statements without
root = root + ...obviously makes a new string and changes
rootto point to it
crumbs.extend(...)obviously does not make a new list and does not change what
This little bit of confusion can arise when you try to access variables between modules without using fully qualified names. You end up with multiple names that initially (following the
import) refer to the same object, but later something changes this.
The solution is just to
import A and refer to
A.crumbs in your test script. That way there is only one canonical name for those objects, and the names are "owned" by the module that changes them.