Programmer Puzzle - Python Swallows A Global
Written by Mike James   
Article Index
Programmer Puzzle - Python Swallows A Global
Solution

Solution

The answer to the problem is that Python doesn't strictly follow the rule that things happen when it encounters the instruction.

In particular when Python encounters a function it reads the function definition and makes a list of the local variables that the function uses.  This list is used to define which variables are local to the function when the function is executed. 

So what happens when the example function definition is read by the Python interpreter is that it makes a list of local variables and i is used in the for loop so it is obviously a local variable. 

def test():
   print( i)
   for i in range(10):
      print( i)

When the function is executed the print(i) instruction causes the Python interpreter to look for a variable called i. The rule is that it always looks for a local variable and if it can't find one then it looks for a global variable. In this case it finds a local variable, as i is used in the for loop, but at this point in the program i is an undefined local variable. 

Now it is perfectly clear why trying to use i causes a runtime error. 

The principle is that assigning a value to a variable anywhere within a function makes that variable local to the entire function. It doesn't matter where the variable is assigned to within the function - it is local. 

 

Pattern

The pattern that you need to follow to make sure that you don't suddenly lose access to a global variable is - don't use global variables in functions. If you need to share a variables between functions then setup a static class attribute.

There is an alternative way of dealing with the problem and this is to use the global keyword. If you write:

global i

within the function that i will be treated as a global variable even if there is an assignment to the variable within the function. Notice that you can put the global statement in anywhere within the function and it has the same effect. That is a variable is global for the entire function. 

However this doesn't solve the problem of the strange mixed global then local use of i within the example function. Once a variable is defined as being global it is always global. 

What this means is that:

def test():
   global i
   print( i)
   for i in range(10):
      print( i)

works as long as i is initialized in the main program but in this case the for loop changes the value in the global variable. This  is probably not what you want at all.

So to summarize:

  • In  Python function definitions are used to create a list of local variable and a variable is local for the entire function and you can't use a variable before you have initialized it. 

  • The global keyword converts a variable reference into a global variable and it remains global for the entire function. 

  • Because being local or global applies throughout the entire function a variable cannot change its scope as a function executes. 

Banner

  • Mike James is the author of Programmer's Python: Everything is an Object published by I/O Press as part of the  I Programmer Library. With the subtitle "Something Completely Different" this is for those who want to understand the deeper logic in the approach that Python 3 takes to classes and objects.

More Puzzles

Sharpen Your Coding Skills
The Best Sub-Array Problem

At first glance this puzzle seems trivial, all you have to do is find a sub-array, in an array of numbers,  that sums to the largest value. It sounds almost too easy to need a solution, let alone [ ... ]


Sharpen Your Coding Skills
Self-Descriptive Arrays

Put on your thinking cap for another set of conundrums that will exercise your coding skills. This time Melvin Frammis introduces his junior partner Bugsy Cottman to some classic number puzzles that c [ ... ]


Sharpen Your Coding Skills
The Post Production Problem

Joe Celko has posed another puzzle that requires you to think like a programmer. This one is all about Post tag machines, which have absolutely nothing to do with mail of any type but a lot to do with [ ... ]


Other Articles

    <ASIN:1871962587>

    <ASIN:B07S1K8KLW>