3

This is (I assume) a basic question, but I can't seem to figure it out.

Given the following code:

from src.Globals import *
import pygame
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
# This is a list of 'sprites.'
block_list = pygame.sprite.Group()

def update_screen():
    # Loop until the user clicks the close button.
    done = False
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True

        # Clear the screen
        screen.fill(WHITE)

        for i in blocks:
            block_list.add(block)

        block_list.draw(screen)

        # Limit to 20 frames per second
        clock.tick(20)

        # Update the screen with what we've drawn.
        pygame.display.flip()

    pygame.quit()

Everything works fine. I can call the function update_screen in a thread and have it work correctly. However, if I move done = False above the function declaration, then I get the error: UnboundLocalError: local variable 'done' referenced before assignment.

My question is: why is it that I can safely have clock, and block_list outside of the function, but not done?

Teknophilia
  • 758
  • 10
  • 23
  • 1
    You need to declare `global done` at the top of the function so it won't be a local variable. You don't need to do that with `clock` and `block_list` because you don't assign values to them and only reference their current values. – martineau Mar 15 '16 at 03:23
  • 1
    I figured out that using global to actually make it global would help. Your explanation helped make it clear WHY: because I'm not changing the other values. – Teknophilia Mar 15 '16 at 04:32
  • Python follows what's called the [LEGB Rule](http://stackoverflow.com/a/292502/355230) to find variables (and determine whether they are local when assigned). – martineau Mar 15 '16 at 05:32

1 Answers1

3

After moving done variable above function you have to explicitly point interpreter that done variable within function is global

done = False
def update_screen():
    # Loop until the user clicks the close button.
    global done
    while not done:
    # .......

You have to identify variable with global in case if you have direct assignment to that variable, for instance a = 10. In code snippets above everything works fine for clock and block_list because there are no direct assignments to that vars within function body.

That's required because all variables, which value has been assigned in function body is treated as function local vars.

You can find more info by urls below:

Community
  • 1
  • 1
Andriy Ivaneyko
  • 20,639
  • 6
  • 60
  • 82