我目前正在开发一个项目(为了好玩),其中包括创建一个完全可玩的国际象棋游戏!
我尝试在我的项目中创建一个“结构”,并将所有类分隔在不同的文件中......
我还有一个 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)
最佳答案
您有一个循环导入。
在ChessBoard
中导入棋子
:
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 行之后几行定义。
如果您必须访问 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")
关于python - python 中的名称错误(类),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58467452/