# Very important to understand #1 and #2. # #3 is less important for now. Good programming style/design often # avoid situations like those in #2. ##### #1. simple local variable example def f(x): y = 1 x = x + y print("x (as seen inside function f) has value: {}".format(x)) return x # Then do, in interpreter: # x = 3 # y = 2 # z = f(x) # z # y # x # # The key point: there are two different x variables as well as two # different y variables. ##### # 2. It is important that you understand this longer example, and why all the # variables have the values they do when printed out. # Draw stack frames by hand to help understand it! # def fn3(x): print("Entered fn3. Local x = ", x, "non-local z = ", z) y = 3 * x + 3 + z x = y + 3 print("Leaving fn3. Local x =", x, "y =", y) return x def fn2(x): print("Entered fn2. Local x = ", x) z = 4 y = 2 * x + z + 2 x = fn3(y) + 2 print("Leaving fn2. Local x = ", x, "y =", y, "z = ", z ) return x def fn1(x): print("Entered fn1. Local x = ", x) y = x+1 x = fn2(y)+1 print("Leaving fn1. Local x = ", x, "y =", y) return x # execute of the following in Python. But also do "by hand" on paper, # drawing stack frames to keep track of different variables/values # >>> x = 0 # >>> z = 5 # >>> fn1(x+1) # >>> x # 1 # >>> z # 5 ##### # 3. special small examples: # f1: accessing global/non-local value (if a variable is mentioned in a function but *not* assigned-to, # then it references the global value # f1() crashes if no global x value has been set # f1() prints global x value if one has been set def f1(): print(x+1) # f2: call to f1, f1 still accesses "top level"/global x, not f2's local x! def f2(): x = 1 print(x) f1() # f3: oddly demonstrates python rule of: if you assign to variable in function body # that variable is local. This function does *not* first access non-local/global x, then # assign to local (or global x). Instead it ??? (try it) def f3(): print(x) x = 1