Python repr & passing class instances as params

424 views Asked by At

So I have a class that I've set something like

class Piece: 
    def __init__(): 
        self.txt = "\u2665"

    # some methods...
    # including a method validMovements(), which works properly, no errors here

    def __repr__():
        return self.txt

Now i proceed to doing the following code

class GameManagement: 
    # various methods, no errors here

    def calculatePossibleMoves() # this is called at the end of each turn, for the next turn, this is also calculated in the initialization function of the GameManagement class, the problem is not here
        self.possibleMoves = {}
        for piece in self.piecesDict:  # contains all pieces
            self.possibleMoves[piece] = piece.validMovements()

Then, in another class, I use this variable

# note that self.selection contains an instance of the Piece class object
# and self.game contaisn a GameManaement class object
l = self.game.possibleMoves[self.selection]
# i get my error here, it seems liek in the GameManagement class, the dict uses the calss instance as key, however her it uses __repr__ as the key, instead of the object

Is there anyway to fix this (read details in the comments)?

The traceback goes as follows:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python33\lib\tkinter\__init__.py", line 1475, in __call__
    return self.func(*args)
  File "C:\Users\Saume\Workspace\ChessUI\src\ui\gameboard.py", line 189, in select
    self.move(event) # call move
  File "C:\Users\Saume\Workspace\ChessUI\src\ui\gameboard.py", line 205, in move
    self.draw()
  File "C:\Users\Saume\Workspace\ChessUI\src\ui\gameboard.py", line 142, in draw
    self.createcanvas()
  File "C:\Users\Saume\Workspace\ChessUI\src\ui\gameboard.py", line 120, in createcanvas
    l = self.game.aJouer[self.selection]
KeyError: ♙

Note, some of my code in the traceback is in french, but it goes exactly how i put it up there.

def select(self, event):
        """Selectionne une piece"""
        if self.selection == None: # il n'y a pas de selection
            try: 
                # coordonnees
                x = event.x // self.size
                y = event.y // self.size
                # piece
                p = self.game.board.getPiece(y, x)
                if p != None: 
                    if p.color == (self.game.time + 1) % 2: # piece de couleur alliee au joueur actuel 
                        self.selection = p
                    else: # piece ennemie
                        raise err.InvalidSelection("La piece selectionnee n'est pas de votre couleur.")
                else: 
                    raise err.EmptySelection("Il n'y a aucune piece sur la case selectionnee.")

            except err.InvalidSelection as e: 
                self.errorLabel.config(text=e) # afficher le message d'erreur
            except err.EmptySelection as e: 
                self.errorLabel.config(text=e) # afficher le message d'erreur
        else: # il y a deja une piece selectionnee
            self.move(event) # call move
        self.draw()
1

There are 1 answers

0
andrew cooke On BEST ANSWER

the error is pretty clear - self.game.aJouer does not include, as a key, the piece that is in self.selection.

note that you do not show any code that guarantees this. in fact, you don't show any code that shows aJouer at all.

the __repr__ result is not used as key. you are being misled by the error message. when python wants to display an instance (eg when it is reporting an error), it calls __repr__. that is all that is happening there. there is no confusion between __repr__ and the actual instance.

in fact, what is used as a key is the value returned by __hash__ (which works along with __equals__ in the hash algorithm in dict). but if you have not replaced that then the default version should work just fine.