> It seems that in the first case change_value() called in module_b.py > ignores the global statement. Is it so? Why? What happens in the second > case? I really don't get it.
The key is that it doesn't ignore the global statement, but that global specifically points to the variable 'value' in module A's namespace. That is, even though you call change_it() from module B, it acts on the variable in module A, not B, even though 'value' exists in B. consider the following modules: module_a.py value = 'initial' def change_it(): global value value = 'changed' def print_it(): print "In module A:", value print_it() module_b.py from module_a import value, change_it, print_it as a_print_it() def print_it(): print "In module B:", value print_it() change_it() a_print_it() print_it() $> python module_b.py In module A: initial In module B: initial In module A: changed In module B: initial Here we see that a) print_it() was executed in module A before the code in module B ran; This happens at import. b) after change_it() was executed, 'value' in module A was changed, while 'value' in module B was left alone. This demonstrates how the modules have separate namespaces, but also hinges on the fact that strings are immutable, as star.public mentions. 'value' in both namespaces do refer to the same object. What's significant is the action on the method change_it(). For example, def change_it(): value = 'changed' this would do no good at all, as you may have realized, as it merely assigns the string 'changed' to the name/variable 'value' in the function namespace. If there is an assignment to a variable in a function (not an attribute of some other variable), such as 'a = 2', the interpreter assumes that the function is declaring a new variable. We need to explicitly declare the variable global first. If we don't, and try to treat it global, the above useless function can result, or the following def change_it(): if value == 'initial': value = 'changed' which results in a UnboundLocalError, since, defaulting to using 'value' as a local variable (since we have the assign statement `value = 'changed'`), and we attempt to use the local var before assigning it a value. For mutable objects, such as a list, or classes (and their attributes), the result would be different. module_a.py value = ['initial'] def change_it(): value[0] = 'initial' # don't need the 'global value', since we're accessing attributes # of 'value', not directly accessing value def print_it(): print "In module A:", value[0] print_it() module_b.py from module_a import value, change_it, print_it as a_print_it def print_it(): print "In module B:", value[0] print_it() change_it() a_print_it() print_it() $> python module_b.py In module A: initial In module B: initial In module A: changed In module B: changed In this case, the two module namespaces still each contain a reference to the same object. What we did differently is change the object itself, instead of the reference. If change_it() assigned to value, `value = ['changed']`, we would see no different behavior than in the first case. Sorry if that was overly winded. scope and namespaces are tricky (at least for me) to explain. - Jeremy -- http://mail.python.org/mailman/listinfo/python-list