#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    6
    Rep Power
    0

    Error message when trying to use global and local variables


    this problem likely has a simple solution, but I haven't been able to find one yet.

    I'm using the book "invent your own computer games with python" and I've found an example that gives an error when trying to run it. the example is supposed to show how to use global and local variables and their differences. the code looks like this:

    Code:
    # This block doesn't run until testValue() is called:
    def testValue():
        # We read the global variable's value:
        print(spam) # 42
        
        # We create a local variable named "spam"
        #instead of changing the value of the global variable "spam":
        spam = 99
        
        # The name "spam" now refers to the local
        # variable only for the rest of this function:
        print(spam) # 99
        
    # A global variable named "spam":
    spam = 42
    
    # Call the testValue() function:
    testValue()
    
    # The global variable was not changed in testValue():
    print (spam) # 42
    the error given when attempting to run it is this:

    Code:
    Traceback (most recent call last):
      File "C:\Python33\global_vs_local.py", line 18, in <module>
        testValue()
      File "C:\Python33\global_vs_local.py", line 4, in testValue
        print(spam) # 42
    UnboundLocalError: local variable 'spam' referenced before assignment
    the only solution I've found to the problem makes it so the program prints

    42
    99
    99

    as if 99 stored in "spam" is the global variable when it should print (according to the comments)

    42
    99
    42

    is there a way to fix this error and the values printed?
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,997
    Rep Power
    481
    If a variable appears as the target of an assignment in a function that variable is local to the function. Remember, python parses the code before executing it. Python knows the scope and the error message is correct.
    You can make the variable global using the global statement.

    Looks like your tutorial is in error.
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    100
    Rep Power
    2
    OK, here's your code:
    Code:
    spam = 42 # For convention, let's define the global variable first
    def testValue():
        print(spam) 
        spam = 99
        print(spam) 
    
    testValue()
    print (spam)
    Here's how Python executes this code:
    When it sees the 'print' statement and finds the variable defined, it simply prints its value:
    Code:
    >>> spam = 42
    >>> def testValue():
                 print(spam)
    >>> testValue()
    42
    Now, when Python sees the variable 'spam' defined again after printing the value, it raises an error saying that you defined it before assignment. To avoid such name collisions, either use the 'global' statement or change the name:
    Code:
    >>> spam = 42
    >>> def testValue():
                 print(spam)
                 spam1 =  99
                 print(spam)
    >>> testValue()
    42
    99
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    6
    Rep Power
    0
    Originally Posted by Akshat1
    OK, here's your code:
    Code:
    spam = 42 # For convention, let's define the global variable first
    def testValue():
        print(spam) 
        spam = 99
        print(spam) 
    
    testValue()
    print (spam)
    Here's how Python executes this code:
    When it sees the 'print' statement and finds the variable defined, it simply prints its value:
    Code:
    >>> spam = 42
    >>> def testValue():
                 print(spam)
    >>> testValue()
    42
    Now, when Python sees the variable 'spam' defined again after printing the value, it raises an error saying that you defined it before assignment. To avoid such name collisions, either use the 'global' statement or change the name:
    Code:
    >>> spam = 42
    >>> def testValue():
                 print(spam)
                 spam1 =  99
                 print(spam)
    >>> testValue()
    42
    99
    ok, I understand why changing the name of the second variable named "spam" corrects the problem so the program correctly prints

    42
    99
    42

    but the example in the book was supposed to show that attempting to modify global variables on a local scope will create a local variable with the same name. defining the global variables like:

    Code:
    # This block doesn't run until testValue() is called:
    def testValue():
        # We read the global variable's value:
        global spam
        print(spam) # 42
        
        # We create a local variable named "spam"
        #instead of changing the value of the global variable "spam":
        spam = 99
        
        # The name "spam" now refers to the local
        # variable only for the rest of this function:
        print(spam) # 99
        
    # A global variable named "spam":
    global spam
    spam = 42
    
    # Call the testValue() function:
    testValue()
    
    # The global variable was not changed in testValue():
    global spam
    print (spam) # 42
    makes it so the program prints

    42
    99
    99

    which goes against the principle the book is attempting to teach as if the value "99" has become the global variable.

    I'm a beginner so I'm not sure if what the book is trying to teach is wrong and the output after defining the global variables is correct. if that's the case, why does the value 99 get printed if it's not the global variable?
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    100
    Rep Power
    2
    Originally Posted by mulebuck
    but the example in the book was supposed to show that attempting to modify global variables on a local scope will create a local variable with the same name. defining the global variables like:

    Code:
    # This block doesn't run until testValue() is called:
    def testValue():
        # We read the global variable's value:
        global spam
        print(spam) # 42
        
        # We create a local variable named "spam"
        #instead of changing the value of the global variable "spam":
        spam = 99
        
        # The name "spam" now refers to the local
        # variable only for the rest of this function:
        print(spam) # 99
        
    # A global variable named "spam":
    global spam
    spam = 42
    
    # Call the testValue() function:
    testValue()
    
    # The global variable was not changed in testValue():
    global spam
    print (spam) # 42
    The last line of your comment "The global variable was not changed in testValue()" is actually wrong! You indeed change the global name. When you say, 'global spam' it means that whatever you'll do, will affect the global variable 'spam':
    Code:
    spam = 42
    def testValue():
        # We read the global variable's value:
        global spam
        print(spam) # we print its value -- 42
        spam = 99 # When we said 'global' earlier it affected our behaviour in the global scope of 'name' and therefore, it printed 42
        print(spam) # # The name "spam" now refers to the global variable 'spam' and when you print it, it prints 99
    
    # When called, we expect the interpreter to print the following:
    # 42   because the global variable's value was 42
    # 99   because the global variable's value has now been changed to 99
    Here's a better way to understand this:

    Code:
    spam = 42
    def testValue():
    	global spam   # referring to the global 'spam'
    	print(spam)   # printing its value
    	spam = 99     # changing the GLOBAL variable since it was mentioned earlier
    	print(spam)   # printing the global variable
    	spam = 42     # when the value of spam is now changed, it again changes the GLOBAL value of 'spam' since you had previously used a global statement
    	print(spam)   # prints the global variable
    testValue()
    print(spam)           # global value of 'spam' -- 42, is changed again!
    It seems to me that you are using a wrong book! Go purchase/download 'Learning Python 4th Edition' (or 5th edition, coming this July!) by Mark Lutz; he is the best tutor of python in the world and his book has no mistakes.




    [/CODE]
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    6
    Rep Power
    0
    ah thank you, I think I understand now. so the program prints "99" again b/c the value of "spam" was changed again. it does not in fact create another local variable of a different value with the same name

    as for books to study, thank you suggesting lutz! I'll definitely look into him

IMN logo majestic logo threadwatch logo seochat tools logo