0

I'm misunderstanding with closures and the code is

Code 1

def test_int():
   a = 1
   def plus():
     print(a)
     a += 1
   plus()

test_int()

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in test_int
  File "<stdin>", line 4, in plus
UnboundLocalError: local variable 'a' referenced before assignment

Code2

def test_int():
   a = 1
   def plus():
     print(a)
     print(locals())
   plus()

test_int()

1
{'a': 1}
  1. Why is code2 correct but code1 is wrong? However, when a is an array, code3 is correct.

Code 3

def test_arr():
   a = [0]
   def plus():
     a[0]+=1
     print(a)
   plus()

test_arr()
[1]
  1. What is the difference between int and array when define a free variable?
Pi Pi
  • 861
  • 3
  • 13
  • 22
  • In reference to your first question, you cannot modify a variable outside the scope of the function. If you added `nonlocal a` it should allow you to replace it's value. – Teejay Bruno Mar 12 '21 at 03:53
  • read `global` `local` `nonlocal` variables https://www.python-course.eu/python3_global_vs_local_variables.php – Epsi95 Mar 12 '21 at 03:53
  • 1
    An assignment statement *anywhere* in a function marks that variable as *local* by the compiler. To be able to *assign* to a variable in a coluse, use the `nonlocal` statement (or `global` statement for global variables) – juanpa.arrivillaga Mar 12 '21 at 04:05
  • 2
    `a` is not an array, but a `list`. The difference *has nothing to do with the types per se*. Rather, `a[0] += 1` does not count as a *simple assignment* since you aren't re-assigning a variable, rather, you are in effect calling `a.__setitem__(0, 1)` – juanpa.arrivillaga Mar 12 '21 at 04:06

1 Answers1

0

Case 1 vs Case 2:

In case 1, you are changing what the variable name is pointing to. That will not work. In case 2, you are not changing what the variable points to. That will work.

Case 3:

In this case, the variable is a mutable (list). You are mutating the object (in place) and not changing what it points to. Therefore, it will work like Case 2.

PiperWarrior
  • 191
  • 1
  • 13