2012-05-23 12 views
6

Estoy tratando de averiguar por qué obtengo un UnboundLocalError en mi aplicación de juego de ajedrez, Table Wars. He aquí un resumen de lo que sucede:Error local sin consolidar con la variable global

Las variables, REDGOLD, REDCOMMAND, BLUEGOLD y BLUECOMMAND, se inicializan como variables globales:

#Red Stat Section 
REDGOLD = 50 
REDCOMMAND = 100 
#Blue Stat Section 
BLUEGOLD = 50 
BLUECOMMAND = 100 

def main():  

    [...] 

    global REDGOLD 
    global REDCOMMAND 
    global BLUEGOLD 
    global BLUECOMMAND 

Esto funciona cuando el desove unidades dentro del bucle principal, restando fondos para desovar unidades.

En este momento, estoy tratando de establecer un sistema para que cuando una unidad muere, las restituciones asesinas de COMMAND la víctima y gana GOLD basan en lo mató:

class Red_Infantry(pygame.sprite.Sprite): 
def __init__(self, screen): 
    [...] 
    self.reward = 15 
    self.cmdback = 5 

[...] 

def attack(self): 
    if self.target is None: return 
    if self.target.health <= 0: 
     REDGOLD += self.target.reward   #These are the problem lines 
     BLUECOMMAND += self.target.cmdback  #They will cause the UnboundLocalError 
               #when performed 
     self.target = None 
    if not self.cooldown_ready(): return 
    self.target.health -= self.attack_damage 
    print "Target's health: %d" % self.target.health 

Esto funciona hasta el mismo la unidad muere Entonces esto sucede:

Traceback (most recent call last): 
File "C:\Users\Oventoaster\Desktop\Games\Table Wars\Table Wars.py", line 606, in <module> 
main() 
File "C:\Users\Oventoaster\Desktop\Games\Table Wars\Table Wars.py", line 123, in main 
RedTeam.update() 
File "C:\Python27\lib\site-packages\pygame\sprite.py", line 399, in update 
for s in self.sprites(): s.update(*args) 
File "C:\Users\Oventoaster\Desktop\Games\Table Wars\Table Wars.py", line 304, in update 
self.attack() 
File "C:\Users\Oventoaster\Desktop\Games\Table Wars\Table Wars.py", line 320, in attack 
REDGOLD += self.target.reward 
UnboundLocalError: local variable 'REDGOLD' referenced before assignment 

¿Cómo consigo las variables globales antes mencionadas a cambiar con el bloque attack? Si ayuda, estoy usando Pygame 2.7.x, por lo que no va a funcionar nonlocal:/

Respuesta

9

global hacer visible la variable global en el bloque de código actual. Solo pone la declaración global en main, no en attack.

ADENDA

Aquí es una ilustración de la necesidad de utilizar más global de una vez. Pruebe esto:

RED=1 

def main(): 
    global RED 
    RED += 1 
    print RED 
    f() 

def f(): 
    #global RED 
    RED += 1 
    print RED 

main() 

Aparecerá el error UnboundLocalError: local variable 'RED' referenced before assignment.

Ahora elimine el comentario de la declaración mundial de f y funcionará.

La declaración global es activo en un léxico, no un alcance dinámico.

+0

eso es exactamente lo que yo hizo. Las variables globales se llaman en el bucle principal, justo después de que la función 'main()' configura la pantalla e inicializa el reloj – Oventoaster

+0

Eso funciona maravillosamente. ¡Gracias! – Oventoaster

3

tiene que declarar la variable como global en cada ámbito en el que se están modificando

Mejor aún encontrar una manera de no utilizar variables globales. ¿Tiene sentido que esos sean atributos de clase, por ejemplo?

1

encontrado que las variables en main actúan como variables globales "sólo lectura" en la función. Si tratamos de reasignar el valor, generará un error.

Probar:

#!/usr/bin/env python 
RED=1 
A=[1,2,3,4,5,6] 

def f(): 
    print A[RED] 

f() 

Está bien.

Pero:

#!/usr/bin/env python 
RED=1 
A=[1,2,3,4,5,6] 

def f(): 
    print A[RED] 
    A = [1,1,1,1,1] 

f() 

Generar

File "./test.py", line 6, in f 
    print A[RED] 
UnboundLocalError: local variable **'A'** referenced before assignment 

y:

#!/usr/bin/env python 
RED=1 
A=[1,2,3,4,5,6] 

def f(): 
    print A[RED] 
    RED = 2 

f() 

Generar

File "./test.py", line 6, in f 
    print A[RED] 
UnboundLocalError: local variable **'RED'** referenced before assignment 
Cuestiones relacionadas