NameError (Class) в Python - PullRequest
       3

NameError (Class) в Python

2 голосов
/ 19 октября 2019

В настоящее время я работаю над проектом (для развлечения), который состоит из создания полностью играбельной шахматной игры! Я попытался создать «структуру» в своем проекте и разделил все мои классы в разных файлах ... У меня также есть файл luncher.py, который необходимо выполнить для запуска игры. Но я получаю сообщение об ошибке при его выполнении:

Traceback (most recent call last):
  File "d:/Paul/Document/Python/Projet Echecs/luncher.py", line 12, in <module>
    from classes.ChessBoard import *
  File "d:\Paul\Document\Python\Projet Echecs\classes\ChessBoard.py", line 4, in <module>
    from classes.Pieces import *
  File "d:\Paul\Document\Python\Projet Echecs\classes\Pieces.py", line 15, in <module>
    class Pieces(ChessBoard):
NameError: name 'ChessBoard' is not defined

Вот структура проекта:

  • Папка проекта:
    • Папка Классы:
      • ChessBoard.py
      • Pieces.py
      • Rook.py
    • Папка img: со всеми изображениями
    • luncher.py (корневой файл)

Вот код каждого файла:

luncher.py:

'''Ce fichier est le fichier root du projet! 
C'est lui qu'i faut executer pour le lancer!
'''

#On importe les modules necessaires
from tkinter import *
from classes.ChessBoard import *

#On creer un fenetre, puis l'échiquier (On appelle la classe ChessBoard)

fenetre = Tk()
fenetre.title("Echecs")
test = ChessBoard(fenetre, 650, 650)
fenetre.mainloop()

ChessBoard.py:

# On importe tous les modules necessaire au bon fonctionnement de la classe
from tkinter import *
from classes.Pieces import *
import os

# Creation de la classe

class ChessBoard:
    # On initialise l'objet
    def __init__(self, window, height=650, width=650, color="#546760", wdCase=76):
        '''
        Parametre obligatoire: - une fenetre TKinter
        Parametres facultatifs: -hauteur de la fenetre
                                - largeur de la fenetre
                                - couleur des cases
                                - largeur des cases
        '''

        self.height = height
        self.width = width
        self.backgroundColor = color
        self.wdCase = wdCase
        self.window = window
        self.game = self.getGame()


        self.rows = ["1", "2", "3", "4", "5", "6", "7", "8"]
        self.columns = ["A","B","C","D","E","F","G","H"]

        # On creer le plateau
        self.board = Canvas(self.window, height=self.height, width=self.width)
        self.board.pack()

        self.case = [[self.board.create_rectangle(i * self.wdCase, j * self.wdCase, (i+1) * self.wdCase, (j+1) * self.wdCase,fill = "#F3F3F3")for i in range(8)] for j in range(8)]
        self.board.create_line(2, 2, 2, self.wdCase * 8)
        self.board.create_line(2, 2, self.wdCase * 8, 2)

        # On implemente les couleurs des cases qui peuvent etre modifiées en passant color=.... en parametre

        for i in range(0,8,2):
            for j in range(1,9,2):
                self.board.itemconfigure(self.case[i][j],fill=self.backgroundColor)
                self.board.itemconfigure(self.case[j][i],fill=self.backgroundColor)

        # On implemente les labels de lignes et de colonnes : A-F et de 1-8
        # On créer une variable locale pour les coordonnées des lettres et des chiffres a place dans le Canvas
        textPositionX = self.wdCase / 2
        textPositionY = self.wdCase / 2
        a = (self.wdCase) * 8 + (self.wdCase / 4)

        for i in range(8):

            self.board.create_text(textPositionX, a, text=self.columns[i])
            self.board.create_text(a, textPositionY, text=self.rows[-i - 1])
            textPositionX += self.wdCase
            textPositionY += self.wdCase

        # On peut maintenant générer les pieces

        test = Rook(303, 532, "Noir")

    def getGame(self):
        """
            Cette méthode de la classe ChessBoard permet de récuperer une partie en cours si il en existe
            une et dans le cas contraire créer une nouvelle partie.

            Dans tous les cas, la methode renvoie un tableau décrivant la disposition des pieces sur le plateau.
        """

        # On verifie si le fichier saves.txt existe
        if os.path.exists("saves.txt"):
            # Si il existe, on l'ouvre et on recupere les donnees
            with open("save.txt") as save:
                #A FINIR
                pass
        else:
            #Sinon on creer une nouvelle partie
            piece = [["."]*8]*8
            piece[0] = ["TN", "CN", "FN", "DN", "RN", "FN", "CN", "TN"]
            piece[1] = ["PN"]*8
            piece[7] = ["TB", "CB", "FB", "DB", "RB", "FB", "CB", "TB"]
            piece[6] = ["PB"]*8

            return piece

Pieces.py

'''Ce module contient la classe Piece'''

# On importe les modules necessaires
from tkinter import *
from classes.ChessBoard import *

# On peu modifier la variable path pour charger les images
path = "D:\Paul\Document\Python\Projet Echecs\img\Pieces\\"


class Pieces(ChessBoard):

    def __init__(self, X, Y, color):
        self.color = color
        self.coordinateX = X
        self.coordinatY = Y

и наконец Rook.py:

from tkinter import *
from classes.ChessBoard import *
from classes.Pieces import *


class Rook(Pieces):

    def __init__(self, X, Y, color):

        Pieces.__init__(self, X, Y, color)

        self.img = PhotoImage(file=path + "T{}.gif".format(self.color[0].upper()))
        self.board.create_image(self.coordinatX, self.coordinatY, anchor=NW, image=self.img)

1 Ответ

3 голосов
/ 19 октября 2019

У вас есть круговой импорт.

В ChessBoard вы импортируете Pieces:

from classes.Pieces import *

На данный момент ChessBoard в основном пусто ,потому что единственная строка, которая завершила выполнение - это from tkinter import *.

И при импорте Pieces вы затем импортируете этот пустой ChessBoard модуль:

from classes.ChessBoard import *

Нет ChessBoard класс на данный момент;все, что вы импортировали, это tkinter имена.

Вы можете увидеть это в трассировке:

  File "d:/Paul/Document/Python/Projet Echecs/luncher.py", line 12, in <module>
    from classes.ChessBoard import *

ChessBoard импортируется luncher.py

  File "d:\Paul\Document\Python\Projet Echecs\classes\ChessBoard.py", line 4, in <module>
    from classes.Pieces import *

, который в строке 4 импортирует Pieces, а

  File "d:\Paul\Document\Python\Projet Echecs\classes\Pieces.py", line 15, in <module>
    class Pieces(ChessBoard):

пытается использовать ChessBoard, но этот класс определяется только несколькими строками после строки 4.

Если вы должны иметь доступ к классу Pieces в ChessBoard, вам придется переместить строку импорта ниже определения class ChessBoard.

Однако я думаю, что ваша фундаментальная ошибка здесьозначает, что класс Pieces наследуется от ChessBoard на всех . Шахматные фигуры не шахматная доска! Если вам необходимо разделить некоторые функции между классом ChessBoard и классом Pieces, выделите их в отдельный модуль, который затем используют оба.

Наследование классов - это способ обмена функциями , где этоимеет смысл и классифицировать ваши классы. Шахматная доска и фигуры на доске обычно не разделяют функциональность;например, доска не делает ходов и не принадлежит одному игроку или другому.

Отсутствие наследования от класса ChessBoard упростит ваши два других модуля до:

'''Ce module contient la classe Piece'''

# On peu modifier la variable path pour charger les images
path = "D:\\Paul\\Document\\Python\\Projet Echecs\\img\\Pieces\\"

class Pieces:
    def __init__(self, board, X, Y, color):
        self.board
        self.color = color
        self.coordinateX = X
        self.coordinatY = Y

и

from tkinter import *
from classes.Pieces import path, Pieces

class Rook(Pieces):
    def __init__(self, board, X, Y, color):
        Pieces.__init__(self, board, X, Y, color)

        self.img = PhotoImage(file=path + "T{}.gif".format(self.color[0].upper()))
        self.board.create_image(self.coordinatX, self.coordinatY, anchor=NW, image=self.img)

Обратите внимание, что я также дал классу Pieces аргумент board, поскольку вы используете его в Rook.__init__(). Поэтому, когда вы создаете экземпляр Rook, передайте на доску:

test = Rook(self, 303, 532, "Noir")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...