I used to program in C, C# and Java. Now I'm using Python for a while but I encountered some problems with understanding variable scope which is quite confusing for me right now. For example:
def f1():
    print(spam)   # spam magically come from outer scope. ok...
def f2():
    spam = "bbb"  # assignment shadows variable from outer scope (logical result of f1)
    print(spam)   # printing local spam variable
def f3():
    print(spam)   # ERROR: unresolved reference 'spam'
    spam = "ccc"  # in f1 function everything was fine but adding assignment AFTER
                  # printing (in opposite to f2 function) causes error in line above
def f4():
    print(spam)   # nothing wrong here, assignment line below is commented
    # spam = "ccc"
spam = "aaa"
Why on earth functions can reach variables outside their scope? And why shadowing variable from outer scope is ok but only if we didn't use it before?
 
    