2

In this simple code to learn differences about global and local variable:

def sub():
    print(a)
    a="banana"
    print(a)

a="apple" 
sub()
print(a)

I am getting an error:

UnboundLocalError

Traceback (most recent call last) in
5
6 a="apple"
----> 7 sub()
8 print(a)

in sub()
1 def sub():
----> 2 print(a)
3 a="banana"
4 print(a)
5

UnboundLocalError: local variable 'a' referenced before assignment

I am currently understanding that 'a' is a global variable which is declared outside a function.

(It is not declared on any function like main() in C)

But why is this error telling me that 'a' is a local variable?

I know if I add global a above the print(a) line will solve this error, but I want to know WHY.

Timur Shtatland
  • 12,024
  • 2
  • 30
  • 47
JaVirang
  • 125
  • 1
  • 6
  • The short version is that when python compiles the function `sub`, it sees that `a` is declared as a variable inside, and shadows the one on the global scope immediately (rather than waiting until the relevant line of code is actually run). Then, when the code does get run, it hasn't been assigned yet, so you get the error. – Green Cloak Guy Feb 16 '21 at 14:13
  • 1
    it is simply because of the scope of a in your function. The scope starts with the local and then to global. but because you have declared an 'a' within the scope of the function. you will get that error pre-assignment error. which means it has identified that a exists within the function scope, but just referenced after your print() – Ade_1 Feb 16 '21 at 14:15

2 Answers2

4

Python interprets this line: a="banana" in the function as the definition of a new, local, variable a. This variable in the scope of the function replaces the global variable a. Note that print(a) (reference to local variable a) occurs before a="banana" (= assignment). Hence you get the error: UnboundLocalError: local variable 'a' referenced before assignment.

SEE ALSO:
Why am I getting an UnboundLocalError when the variable has a value?
Python gotchas
The 10 Most Common Mistakes That Python Developers Make

Timur Shtatland
  • 12,024
  • 2
  • 30
  • 47
  • 1
    Now I get it. Thanks. I forgot that Python doesn't read each line after other like C. – JaVirang Feb 16 '21 at 14:20
  • Actually, most of the time, python will seem to read each line of the source and 'execute' it before looking at the next. In this case the compiler is trying to create byte codes for the function, but realises there is a contradiction. See [this](https://www.youtube.com/watch?v=DlgbPLvBs30&t=2305s) video for a brilliant and almost complete explanation. – quamrana Feb 16 '21 at 14:27
0

The main reason is by placing

print(a)

inside a function sets variable 'a' as a local variable (i.e, local scope) of that function. Ignoring the

a="apple"

defined outside the function.

And as 'a' value has not been initialized inside the 'sub' function hence its value couldn't be found while executing print(a) hence shows local variable 'a' referenced before assignment which is exactly what happens in the above case.

FOR SUMMARY

def sub():

#     print(a)  #Just comment this and you will understand the difference

## By doing print(a) inside sub function makes sets 'a' as local variable
## whose value has not been initialized
## and as its value couldn't be found while line print(a) executes hence shows
## local variable 'a' referenced before assignment which is exactly what 
##   happens

    a="banana" # a is assigned here 
    print(a)


a="apple" 
sub()
print(a)
Dipendra Pant
  • 365
  • 3
  • 9