-1

When I run the code below:

def run():
  test = False
  def tester():
    if not test:
      print("test is false")
    else:
      print("test is true")
    test = not test
  tester()
run()

I get the error:

local variable 'test' referenced before assignment

I was under the impression that the child function would have access to the parent functions variables. After playing with this code a bit I've found that if I remove the assignment (test = not test) then everything works fine.

Why does having an assignment in the child function break this code? If I shouldn't have the assignment in the child function, what would be the best way to toggle the test flag? Should I just return a value from the child function and use that to toggle test?

Abe Miessler
  • 82,532
  • 99
  • 305
  • 486
  • 2
    Because the compiler/interpreter detects an assignment within the `tester` function, `test` becomes a local variable. Which then, naturally, has no value assigned to in the `if` statement. –  Oct 09 '17 at 02:43
  • Have you tried `nonlocal test`? – adder Oct 09 '17 at 02:45
  • https://stackoverflow.com/questions/419379/how-to-maintain-lists-and-dictionaries-between-function-calls-in-python should help you. – Asclepius Oct 09 '17 at 03:00

1 Answers1

3

Python 2 doesn't support assignments to variables closed over by a nested function. The usual workaround is to put the value in a mutable container (e.g., a one-element list). Python 3 offers the nonlocal keyword for this purpose.

Davis Herring
  • 36,443
  • 4
  • 48
  • 76
  • Would using `nonlocal` be similar to using a global variable? I've heard that using global variables for things like this is generally bad practice - would using `nonlocal` be bad practice as well? – Abe Miessler Oct 09 '17 at 02:50
  • `nonlocal`'s socpe is function but not global, so as far as I think it is not a bad practice as `global` is. – Sraw Oct 09 '17 at 02:51