0

I have been trying to write a Python script that uses global variables. I am getting what seems to be unexpected results in my code. Instead of dumping all the code here, I have created a small piece of code to show what I'm seeing.

def func1():
    global aaa
    aaa = 1

def func2():
    while aaa < 5:
        print(aaa)
        aaa += 1

func1()
func2()

I am expecting to get,

1
2
3
4

What I get instead is,

Traceback (most recent call last):
  File "test2.py", line 11, in <module>
    func2()
  File "test2.py", line 6, in func2
    while aaa < 5:
UnboundLocalError: local variable 'aaa' referenced before assignment

If I change func2 to remove the while loop & just print the aaa variable, it works fine, so the global variable is accessible.

def func1():
    global aaa
    aaa = 1

def func2():
    print(aaa)

func1()
func2()

Running it produces,

1

If I set the aaa value at the top of func2 it also works.

def func1():
    global aaa
    aaa = 1

def func2():
    aaa = 1
    while aaa < 5:
        print(aaa)
        aaa += 1

func1()
func2()

Which results in,

1
2
3
4

I have experience with Perl, but am new to Python. Is there something that I'm missing here?

Paul65
  • 19

1 Answers1

1

global declares the variable to be linked to identically-named variables outside this context for the purposes of changing its value. You have done this for func1, but not for func2.

Since func2 alters a variable aaa that is not declared global, that must be a local variable. When you try to reference your local aaa in the if statement, you get the indicated run-time error.

In your later example, where func2 does not change aaa, the reference print(aaa) is quite legal. Since there's no local aaa, Python searches in the next context outward, and finds the global aaa declared by func1.

Prune
  • 76,765
  • 14
  • 60
  • 81
  • Just so I understand, my thought was that by making a variable global, it could be shared & manipulated in any of the sub routines of my code; not merely referable. But it appears that you're saying that because I am changing the value of the variable, it must be declared to be global. That the global variable that is being shared is one with a set value, Is this correct? – Paul65 Mar 05 '20 at 03:11
  • Previously I have coded in Perl & if you don't specify "use strict", a variable is available and alterable anywhere in your code or defining a variable with "our" would give the variable a global ability to be defined & altered as required. – Paul65 Mar 05 '20 at 03:18
  • 1
    @Paul65 the rule is simple, binding to a name anywhere in a local scope will cause the compiler to mark that variable as *local unless you use the `global` statement*. Merely *accessing* a variable will use the normal scope resolution to try to find it before raising a `NameError`, so local, global, enclosing, built-ins... – juanpa.arrivillaga Mar 05 '20 at 03:27