Using a global variable inside a function nested in a function in Python
Asked Answered
M

2

14

I wonder why my code is not working. I expected that it would return 11 and instead it creates an exception:

def f():

   counter = 1

   def f1():

      global counter

      counter += 1

   while True:

       f1()

       if counter>10:

           return(counter)

f()

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-219-0ec059b9bfe1> in <module>()
----> 1 f()

<ipython-input-218-50c23b042204> in f()
      9         counter += 1
     10 
---> 11     f1()
     12 
     13     if counter>10:

<ipython-input-218-50c23b042204> in f1()
      7         global counter
      8 
----> 9         counter += 1
     10 
     11     f1()

NameError: name 'counter' is not defined

Since counter is declared a global variable and since it appears and defined in the surrounding environment of f1() --inside f()-- why I receive this error message?

Meri answered 2/8, 2018 at 21:34 Comment(0)
H
10

The error is because you are trying to increment the value of the global counter when it has not yet been given a value. The counter in the f() function is in a different scope and a different variable then your global counter in the f1() function.

You have to specify global counter for each scope that you will be using this global variable in. So by doing this it should fix your issue:

def f():
    global counter
    counter = 1

    def f1():
        global counter
        counter += 1

    f1()
    if counter > 10:
        return(counter)

f()

I would also suggest avoiding declaring functions within functions without good reason and from using globals because it can complicate the program. It would be better practice to instead pass counter as an argument to the function and return the result.

An example without using globals or nested functions:

def f():
    counter = 1
    result = f1(counter)

    if result > 10:
        return(result)

def f1(argument):
    argument += 1
    return argument

f()
Halation answered 2/8, 2018 at 21:40 Comment(1)
You don't need to create global. You can use nonlocal https://mcmap.net/q/813818/-using-a-global-variable-inside-a-function-nested-in-a-function-in-pythonColorblind
A
8

It's not a global variable. In the global scope it doesn't exist. Use nonlocal instead of global.

Adorn answered 9/6, 2022 at 20:0 Comment(1)
This makes more sense since and is cleaner. programiz.com/python-programming/…Volz

© 2022 - 2024 — McMap. All rights reserved.