What happens in your program:
main
is defined, with a reference toprintAreas
in its body—note, this is just a reference, not a callprintAreas
is definedmain
is invokedmain
callsprintAreas
.
So all is good—you are allowed to reference any names you want at any time you want, as long as you ensure these names will have been defined (bound to a value) by the time the code containing the reference is executed:
def foo():
print bar # reference to as-of-yet non-existent bar
# calling foo here would be an error
bar = 3
foo() # prints 3