The trick to understanding this is that when you assign to a variable, using =, you also declare it as a local variable. So instead of changing the value of the global variable a, setA(value) actually sets a local variable (which happens to be called a) to the value passed in.
This becomes more obvious if you try to print the value of a at the start of setA(value) like so:
def setA(value):
print "Before assignment, a is %d" % (a)
a = value
print "Inside setA, a is now %d" % (a)
If you try to run this Python will give you a helpful error:
Traceback (most recent call last):
File "scopeTest.py", line 14, in
setA(42)
File "scopeTest.py", line 7, in setA
print "Before assignment, a is %d" % (a)
UnboundLocalError: local variable 'a' referenced before assignment
This tells us that Python has decided that the setA(value) function has a local variable called a, which is what you alter when you assign to it in the function. If you don't assign to a in the function (as with printA()) then Python uses the global variable A.
To mark a variable as global you need to use the global keyword in Python, in the scope that you want to use the global variable. In this case that is within the setA(value) function. So the script becomes:
a = 7
def printA():
print "Value of a is %d" % (a)
def setA(value):
global a
a = value
print "Inside setA, a is now %d" %(a)
print "Before setA"
printA()
setA(42)
print "After setA"
printA()
This one line addition tells Python that when you use the variable a in the setA(value) function that you are talking about the global variable, not a local variable.