Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a global variable inside a function nested in a function in Python

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?

like image 322
user8270077 Avatar asked Aug 02 '18 21:08

user8270077


1 Answers

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()
like image 137
Karl Avatar answered Oct 25 '22 09:10

Karl