python中的namererror(Class)

2024-06-16 16:50:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在做一个项目(为了好玩),其中包括创建一个完全可玩的象棋游戏! 我试图在我的项目中创建一个“结构”,并将我的所有类分隔在不同的文件中。。。 我还有一个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

项目结构如下:

  • 文件夹项目:
    • 文件夹类:
      • 你知道吗棋盘.py你知道吗
      • 你知道吗件.py你知道吗
      • 你知道吗车.py你知道吗
    • 文件夹img:包含所有图像
    • 你知道吗午餐.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)

Tags: infrompyimportselfboardonde
1条回答
网友
1楼 · 发布于 2024-06-16 16:50:41

你有一个循环导入。你知道吗

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 *

ChessBoardluncher.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行之后定义了几行。你知道吗

如果必须有权访问ChessBoard中的Pieces类,则必须将导入行移到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实例时,请使用以下命令传入board:

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

相关问题 更多 >