2016-05-12 9 views
3

Ich versuche, das ui Objekt innerhalb der Pfandklasse zu verwenden und ich definiere und initiiere ui außerhalb alles, also ist es global richtig? Ich habe hier nach Fragen zur Verwendung von Variablen außerhalb von Klassen gesucht, aber sie scheinen sich alle auf .sel zu beziehen, die ich beim Initiieren des Chess-Objekts in der UI-Klasse verwendet habe.Warum kann ich nicht auf eine Instanz einer Klasse zugreifen, die global in einer anderen Klasse definiert ist?

Die # repräsentieren Code-Bits, die ich ausgeschnitten habe, um die Lesbarkeit zu erleichtern.

class UI: 
    def ___init__(self): 
     self.chess = Chess() 
     # Calls main menu function which goes to a new game option 

    def newGame(self): 
     self.chess.startGame() 
     while len(self.chess.pieces[0] == 2): # Which is index for Kings 
      # Game, which is where *move* is called 

class Chess: 
    def startGame(self): 
     self.chessBoard = Grid(9,9) 
     self.pieces = [] 
     self.pawns = [] 
     for i in range(8): 
      self.pawns.append(PawnObject(x,y,side)) 
     self.pieces.append(self.pawns) 

class Grid: 

    # Init method 

    def cellOccupied(self,x,y): 
     # This function checks if a place is empty 
     # If empty, return false else, true 

class Object: 
    # Sets x, y, width, height 


class ChessPiece: 
    # Child of Object sets side (black or white) 

class PawnObject: 
    def move(self,newX,newY): 
     if ui.chess.chessBoard.cellOccupied(newX,newY) == False: 
      # Move 

     # More code 

ui = UI() 

Traceback: https://gyazo.com/33e5b37b5290ff88433b29874c117ad7

Bin ich etwas blendend falsch? Ich denke, die Art und Weise, wie ich das alles programmiert habe, ist sehr ineffizient, da ich immer noch lerne, also ist das ein Ergebnis davon? Vielen Dank.

+3

Ich denke, Sie haben zu viele Informationen ausgeschnitten; Wir können nicht sehen, was das PawnObject erzeugt und 'move' aufrufen - wenn der Fehler tatsächlich dort auftritt, was wir auch nicht sicher wissen. Bitte zeigen Sie zumindest den vollständigen Traceback. –

+1

@ user3457241 - 'PawnObject' ist in Ihrem Code-Auszug kein Kind von' ChessPiece' ... klicken Sie auf die Bearbeitungsschaltfläche unter den Tags Ihrer Frage und korrigieren Sie diese bitte. Löschen Sie dann Ihren Kommentar, der das sagt.Es sei denn, Sie denken, dass Ihr Code richtig geschrieben ist. In diesem Fall werde ich Sie wissen lassen, dass Sie falsch liegen ... das könnte Teil Ihres Problems sein. – ArtOfWarfare

+0

@DanielRoseman Wenn die Funktion startGame() aufgerufen wird, werden alle Teile zur Liste der Teile hinzugefügt, die zum Gitter hinzugefügt werden. Die Move-Funktion wird innerhalb der Benutzeroberfläche in der Hauptschleife eines Schachspiels aufgerufen, wenn der Spieler entschieden hat, ein Stück irgendwo zu bewegen. Wäre es hilfreich, den gesamten Code anzuzeigen? Ich habe den Traceback meinem Post hinzugefügt. –

Antwort

0

Sie verwenden wahrscheinlich ui im Rumpf einer Klasse, die in dem Moment ausgeführt wird, in dem der Interpreter die Klasse sieht (und daher vor ui existiert). Sie können es nur innerhalb von Methoden oder Funktionen verwenden, da diese nur ausgeführt werden, wenn sie aufgerufen werden. Mit anderen Worten:

class UI: 
    def open(self): 
     pass 

class Chess: 
    ui.open() # <--- this causes an error because it happens before the last line does 
    def startGame(self): 
     ui.open() # <--- this is OK 

ui = UI() 

Außerdem glaube ich, Ihre Nachricht zeigt an, dass Sie global ui irgendwo geschrieben, die nur, wenn Sie einen neuen Wert ui auf Zuweisung vorhast notwendig ist, das heißt ui = something. Wenn Sie es nur verwenden möchten, z.B. ui.open(), Sie benötigen keine globale Deklaration. Aber das Entfernen wird Ihr Problem nicht lösen.

Sie müssen auch

chessBoard = Grid(9,9) 

zu

self.chessBoard = Grid(9,9) 

machen chessBoard ein Attribut Chess, die Sie zu sagen ui.chess.chessBoard Lage sein müssen, korrigieren.

1

Das Problem ist, dass diese kaskadierende Reihe von Ereignissen alle innerhalb der Initialisierungsfunktion für UI passiert; Eine Klasse ruft die nächste an, bevor das Original __init__ eine Chance hatte zurückzukehren. Dies bedeutet, dass die Zeile, die diese Initialisierung ausgeführt hat, noch nicht abgeschlossen ist. Die ui Variable existiert noch nicht.

Sie sollten versuchen, etwas davon aus dieser Kaskade zu entfernen. Insbesondere kann ich nicht sehen, warum die Bauern als Folge der Initialisierung der UI-Klasse bewegen sollten; das scheint überhaupt keinen Sinn zu ergeben.

Sie sollten auch überlegen, warum Sie ui als globale Variable benötigen; es scheint wahrscheinlicher, dass es ein Attribut einer der Klassen sein sollte, vielleicht Grid, und der Bauer kann über diese Instanz darauf verweisen.

+0

Ich habe es so geändert, dass mainMenu() nicht von init aufgerufen wird, aber nachdem ich das ui initialisiert habe und es funktioniert hat. Ich wusste nie, dass das Objekt nicht existiert, bis die Initialisierung abgeschlossen ist. Ich werde das berücksichtigen, wenn ich das nächste Mal etwas programmiere. Danke: D –