2012-05-23 18 views
6

Próbuję dowiedzieć się, dlaczego otrzymuję UnboundLocalError w mojej aplikacji pygame, Table Wars. Oto podsumowanie tego, co się dzieje:Niezwiązany lokalny błąd ze zmienną globalną

Zmienne, REDGOLD, REDCOMMAND, BLUEGOLD i BLUECOMMAND, są inicjowane jako zmienne globalne:

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

def main():  

    [...] 

    global REDGOLD 
    global REDCOMMAND 
    global BLUEGOLD 
    global BLUECOMMAND 

To działa, kiedy tarła jednostek w obrębie pętli głównej, odejmując fundusze na tarło jednostki.

Teraz próbuję skonfigurować system tak, że kiedy umiera jednostka, refundacje zabójcze ofiary COMMAND i zarabia GOLD na podstawie tego, co zabił:

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 

ten działa aż do momentu jednostka umiera. Wtedy to się dzieje:

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 

Jak uzyskać zmienne globalne wymienionych powyżej, aby zmienić z blokiem attack? Jeśli to pomaga, używam Pygame 2.7.x, więc nonlocal nie zadziała:/

Odpowiedz

9

global utwórz zmienną globalną w bieżącym bloku kodu. Umieszczasz tylko oświadczenie global w main, a nie w attack.

DODATEK

Tutaj jest ilustracją konieczności korzystania globalny więcej niż jeden raz. Wypróbuj to:

RED=1 

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

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

main() 

Otrzymasz błąd UnboundLocalError: local variable 'RED' referenced before assignment.

Teraz odkomentuj globalne stwierdzenie w f, które zadziała.

Deklaracja global jest aktywna w zakresie LEXICAL, a nie DYNAMICZNYM.

+0

to właśnie ja zrobił. Zmienne globalne są wywoływane w pętli głównej, zaraz po tym, jak funkcja 'main()' ustawia ekran i inicjalizuje zegar. – Oventoaster

+0

To działa cudownie. Dziękuję Ci! – Oventoaster

3

trzeba zadeklarować zmienną jako globalną w każdym zakresie, gdzie są one zmodyfikowanej

Jeszcze lepiej znaleźć sposób, aby nie używać globalnych. Czy ma to na przykład takie znaczenie dla atrybutów klasowych?

1

Znaleziono zmienne w main działają jak globalne zmienne "tylko do odczytu" w funkcji. Jeśli spróbujemy ponownie przypisać wartość, wygeneruje błąd.

Spróbuj:

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

def f(): 
    print A[RED] 

f() 

Jest ok.

Ale:

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

Generowanie

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

oraz:

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

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

f() 

Generowanie

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