在另一个类中清除另一个类的属性时,为什么它不起作用?

时间:2017-12-06 15:10:54

标签: python

我正在编写一个函数,使用Pygame在国际象棋中加载以前保存的游戏。我有六个班级:main2, GUI2, navigation2, calc, board and pieces。我存储了存储每个棋子在棋盘类上的位置的属性,如下所示:

class board:
def __init__(self,main):
    self.main = main
    self.pieces = self.main.pieces
    self.prv_pos = []
    self.dict = self.pieces.dict
    A = ["bRook","bKnight","bBishop","bQueen","bKing","bBishop","bKnight","bRook"]
    B = ["bPawn","bPawn","bPawn","bPawn","bPawn","bPawn","bPawn","bPawn"]
    C = [0,0,0,0,0,0,0,"wKing"]
    D = [0,0,0,0,0,0,0,0]
    E = [0,0,0,0,"wQueen",0,0,0]
    F = [0,0,0,0,0,0,0,0]
    G = ["wPawn","wPawn","wPawn","wPawn","wPawn","wPawn","wPawn","wPawn"]
    H = ["wRook","wKnight","wBishop","wQueen",0,"wBishop","wKnight","wRook"]
    self.piece_pos= [A,B,C,D,E,F,G,H]

我还有一个名为main的类,它可以在每个类上传递一个实例,因此我的所有对象都可以通过主类相互交互。因此,在我的导航类中,托管了保存和加载游戏的功能,我写了这个:

class navigation:
def __init__(self,GUI):
    self.GUI = GUI
    self.main = self.GUI.main
    self.piece_pos = self.GUI.main.board.piece_pos
    self.GUI.draw_button("save",self.GUI.SQ_DIM*8,self.GUI.SQ_DIM)
    self.GUI.draw_button("load",self.GUI.SQ_DIM*8,self.GUI.SQ_DIM*3)
    self.GUI.draw_button("exit",self.GUI.SQ_DIM*8,self.GUI.SQ_DIM*5)

def game_save(self):
    file = open("Save file.txt","w")
    for line in self.piece_pos:
        for item in line:
            file.write(str(item)+",")
        file.write("\n")
    file.close()

def game_load(self): #WIP
    self.piece_pos = []
    self.GUI.draw_board()

您可能会注意到game_load函数非常空;那是因为我想在self.piece_pos = []行中检查该属性是否在整个类中被清除。但是当我调用self.GUI.draw_board()函数时,该函数只会将当前电路板位置绘制在类板中piece_pos中,而电路板在GUI中的外观是相同的。我希望python shell中的错误消息告诉我没有self.piece_pos[i][j],但在我看来该属性没有任何改变。

draw_board()的功能存储在班级'GUI'中。

def draw_board(self):
    X = 0
    Y = 0
    Ycounter = False
    sqcounter = False
    #Draw the board
    print("GUI update")
    for i in range(0,8):
        for j in range(0,8):
            print()
            print("Piece at:")
            print(i,j)
            print(self.main.piece_at(i,j))
            pg.draw.rect(self.window, self.sq_colour[i][j],(X,Y,self.SQ_DIM,self.SQ_DIM),0)
            if self.main.piece_at(i,j) == 0:
                print("square empty")
                pass
            else:
                print("square occupied")
                self.window.blit(self.dict[self.main.piece_at(i,j)],(X,Y))

            #Change of X coord
            if X >(self.SQ_DIM*6):
                X = 0
                Ycounter = True
                sqcounter = True
            else:
                X +=(self.SQ_DIM)

            #Change of Y coord
            if Ycounter == True:
                Y +=self.SQ_DIM
                Ycounter = False
            else:
                pass

所以我得出的结论是,我不了解如何全球化piece_pos属性。但我不知道如何解决这个难题?有什么想法吗?

1 个答案:

答案 0 :(得分:0)

这是因为在game_load()中,self.piece_pos引用navigation.piece_pos,而draw_board()使用GUI.main.board.piece_pos引用的对象。

您正在有效地执行此操作

a = [5]
b = a
print(a, b)   # prints [5] [5]

# By reassigning `b` you only change what it refers to,
# it doesn't affect what it used to refer to before.
b = []
print(a, b)   # prints [5] []

# Instead, if you make an *in-place* modification, then the underlying
# object will indeed change, as both names refer to the same object.
a = b = [5]
b.append(3)
print(a, b)  # prints [5, 3] [5, 3]

如果你真的想做出改变,那应该是

def game_load(self): #WIP
    self.main.board.piece_pos = []
    self.GUI.draw_board()

由于navigation类是GUI的包装器,因此最好摆脱self.piece_pos并使用函数调用来获取/设置片段位置,例如,

def get_piece_pos(self):
    return self.main.board.piece_pos

def set_piece_pos(self, new_pos):
    self.main.board.piece_pos = new_pos

总的来说,我没有看到这堂课的重点。保存/加载/退出按钮属于GUI,相应的保存/加载功能也是如此。我只是将这个功能集成到GUI类中,因为这是用户与之交互的对象。