49

my code is as follow:

done = False

def function():
    for loop:
        code
        if not comply:
            done = True  #let's say that the code enters this if-statement

while done == False:
    function()

For some reason when my code enters the if statement, it doesn't exit the while loop after it's done with function().

BUT, if I code it like this:

done = False

while done == False:
    for loop:
    code
    if not comply:
        done = True  #let's say that the code enters this if-statement

...it exits the while loop. What's going on here?

I made sure that my code enters the if-statement. I haven't run the debugger yet because my code has a lot of loops (pretty big 2D array) and I gave up on debugging due to it being so tedious. How come "done" isn't being changed when it's in a function?

codeforester
  • 39,467
  • 16
  • 112
  • 140
cYn
  • 3,291
  • 6
  • 25
  • 43
  • Does this answer your question? [Python overwriting variables in nested functions](https://stackoverflow.com/questions/7935966/python-overwriting-variables-in-nested-functions) – user202729 Feb 01 '21 at 01:21

4 Answers4

65

Your issue is that functions create their own namespace, which means that done within the function is a different one than done in the second example. Use global done to use the first done instead of creating a new one.

def function():
    global done
    for loop:
        code
        if not comply:
            done = True

An explanation of how to use global can be found here

Community
  • 1
  • 1
Snakes and Coffee
  • 8,747
  • 4
  • 40
  • 60
7
done=False
def function():
    global done
    for loop:
        code
        if not comply:
            done = True

you need to use the global keyword to let the interpreter know that you refer to the global variable done, otherwise it's going to create a different one who can only be read in the function.

Tim
  • 41,901
  • 18
  • 127
  • 145
Ionut Hulub
  • 6,180
  • 5
  • 26
  • 55
7

Use global, only then you can modify a global variable otherwise a statement like done = True inside the function will declare a new local variable named done:

done = False
def function():
    global done
    for loop:
        code
        if not comply:
            done = True

Read more about the global statement.

Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
2

Using a class rather than global:

Another way to handle (not use) global variables is to wrap the functions and variables you wish to be global in a class.

While this is a little heavy for this specific case - classes add a host of functionality and flexability to the project. (Personally) highly recommended.

For example:

class Processor():
    """Class container for processing stuff."""

    _done = False

    def function(self):
        """A function which processes stuff."""
        # Some code here ...
        self._done = True

# See the flag changing.
proc = Processor()
print('Processing complete:', proc._done)
proc.function()
print('Processing complete:', proc._done)

Output:

Processing complete: False
Processing complete: True
S3DEV
  • 8,768
  • 3
  • 31
  • 42