# More examples illustrating the scope of variables. x = 3 # A "global" variable - a variable that has global scope y = "abc" # another global-scope variable def f(x): y = x+2 z = y-1 x += 1 return x+y+z #f #The function f has 3 local vars: x, y, z. x is local because it's a # parameter. y and z are local within f because they're assigned to (given # new values in the function. #print z # This will cause an error, because z's scope do not extend beyond f. print x, y # This will print the values of the global-scope vars: 3, "abc". x = f(x) # Here, f is passed the value of global x (3). The value of the # local x is initially also assigned 3, but it's pure coincidence # that it has the same name as the global x. When x is changed to # 4 on the line (x+=1), only the local x is affected. print x # this should print 13. # However, since f returns a value, this value will be assigned to the global # x, so the global value is changed. def swap(x,y): x,y = y,x #swap # Despite what the name of the above function suggests, it doesn't actually # do anything! swap(x,y) print x, y # prints x,y unchanged. # Why? because the x,y inside the function are local (for both reasons: they # appear as parameters, and they were assigned to in the function). The # swapping assignment only affects the local variables, and since the function # returns no value, there's no possibility that it can affect the value of the # globals. This is a way to waste cpu cycles. # The next example gets a little bit more complicated: def g(y): y = 2+x return y #g x = g(x) # First, y is a local var of g, and it is initially given the value of # the global x, which is 13. Now on the line (y = 2+x), the "x" # refers to the external variable x. Note that this x does not appear # as a parameter of g, not is it assigned to in g, thus it is NOT a # local variable of g. # Another way is to explain this is that a function can normally only # have READ access to external variables, not WRITE access. # If g were written as: # def g(y): # y = 2+x # x = 1 # return y # You will get an error: because x is local because it's assign to, but it # cannot be used BEFORE it's given a value. You cannot have both a local and # a global x inside a function. # There is a way to for a function to assign a new value to a global variable, # by first declaring it as global: global x # But you cannot declare variable global that's also a parameter. In # general this technique should be avoided. A function should encapsulate # its computation. Later we will learn how to define classes, which will # be a much a better way for functions to change the values of other variables. ## The scope of variables can be more than just local or global. In Python # it's possible to define a function inside a function: def f(x,y): def g(y): return x+y # g y = g(x) return y+1 #f ## Here, g is local within f. The meaning of g is different from the global # scope function g defined above. Function definitions, just like variable # assignments, also have scope. Furthermore, the variable x of f is local # within f, and external to g. When the function g refers to x, it is # referring to the x inside its "enclosing scope", which is the scope of # f. There are three y's: the global y, the y local to f, and the y local # to g. When a function refers to a variable, it always looks up the variable # in its *closest enclosing scope*.