2012-05-23 2 views
6

Я пытаюсь понять, почему я получаю UnboundLocalError в моем приложении pygame, Table Wars. Вот краткое изложение того, что происходит:Unbound Local Error с глобальной переменной

Переменные, REDGOLD, REDCOMMAND, BLUEGOLD и BLUECOMMAND, инициализируются как глобальные переменные:

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

def main():  

    [...] 

    global REDGOLD 
    global REDCOMMAND 
    global BLUEGOLD 
    global BLUECOMMAND 

Это работает, когда нерест единиц внутри основного контура, вычитая средства на икру единицы.

Прямо сейчас, я пытаюсь настроить систему таким образом, что, когда блок умирает, убийца возвраты жертвы COMMAND и зарабатывает GOLD на основе того, что он убил:

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 

Это работает вплоть до единица умирает. Тогда это происходит:

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 

Как получить глобальные переменные, упомянутые выше, чтобы изменить с attack блока? Если это помогает, я использую Pygame 2.7.x, поэтому nonlocal не будет работать:/

ответ

9

global сделать глобальную переменную видимой в текущем блоке кода. Вы только поместили оператор global в main, а не в attack.

ADDENDUM

Вот иллюстрация необходимости использования глобальной более чем один раз. Попробуйте следующее:

RED=1 

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

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

main() 

Вы получите сообщение об ошибке UnboundLocalError: local variable 'RED' referenced before assignment.

Теперь раскомментируйте глобальное утверждение в f, и оно будет работать.

Объявление global действует в LEXICAL, а не в области DYNAMIC.

+0

Это именно то, что я сделал. Глобальные переменные вызываются в основном цикле сразу после того, как функция 'main()' устанавливает экран и инициализирует часы – Oventoaster

+0

Это работает чудесно. Спасибо! – Oventoaster

3

Вы должны объявить переменную глобальной в каждой области, где они вносятся изменения

еще лучше найти способ не использовать глобалам. Имеет ли смысл, чтобы они были атрибутами класса?

1

Обнаружено, что переменные в main действуют как глобальные переменные «только для чтения» в функции. Если мы попытаемся переназначить это значение, это вызовет ошибку.

Try:

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

def f(): 
    print A[RED] 

f() 

Это нормально.

Но:

#!/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() 

Сформировать

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

и:

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

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

f() 

Сформировать

File "./test.py", line 6, in f 
    print A[RED] 
UnboundLocalError: local variable **'RED'** referenced before assignment 
Смежные вопросы