属性错误:对象没有属性Python。

3

我正在尝试编写Conway生命游戏的版本,但是我一直收到以下消息:'Cell' Object Has no attribute 'nextState'。然而,在请求引用它之前,它似乎应该声明nextState的值。这是我的代码:

from tkinter import *
root = Tk()

class Cell (Button):
    Dead = 0
    Live = 1

    def __init__ (self,parent):
        Button.__init__(self,parent, relief = "raised" , width = 2 , borderwidth = 1 , command = self.onpress)
        self.displayState(Cell.Dead)

    def onpress (self):
        if self.state == Cell.Live:
            self.displayState(Cell.Dead)
        elif self.state == Cell.Dead:
            self.displayState(Cell.Live)

    def setNextState (self , Neighbours):
        if self.state == Cell.Live and (Neighbours < 2 or Neighbours > 3):
            self.nextState = Cell.Dead
        elif self.state == Cell.Dead and Neighbours == 3:
            self.nextState = Cell.Live
        elif self.state == Cell.Dead and Neighbours != 3:
            self.nextState = self.state

    def stepToNextState(self):
        self.displayState(self.nextState)

    def displayState (self , newstate):
        self.state = newstate
        if self.state == Cell.Live:
            self["bg"] = "black"
        if self.state == Cell.Dead:
            self["bg"] = "white"

class Grid:
    def __init__(self,parent,sizex,sizey):
        self.sizex = sizex
        self.sizey = sizey
        self.cells = []
        for a in range (0,self.sizex):
            rowcells = []
            for b in range (0, self.sizey):
                c = Cell(parent)
                c.grid(row=b , column=a)
                rowcells.append(c)
            self.cells.append(rowcells)

    def step (self):
        cells = self.cells
        for x in range (0,self.sizex):
            if x==0: x_down = self.sizex-1
            else: x_down = x-1
            if x==self.sizex-1: x_up = 0
            else: x_up = x+1
            for y in range(0,self.sizey):
                if y==0: y_down = self.sizey-1
                else: Y_down = y-1
                if y==self.sizey-1: y_up = 0
                else: y_up = y+1
                sum = cells[x_down][y].state + cells[x_up][y].state + cells[x][y_down].state + cells[x][y_up].state + cells[x_down][y_down].state +cells[x_up][y_up].state + cells[x_down][y_up].state + cells[x_up][y_down].state
                cells[x][y].setNextState(sum)
            for row in cells:
                for cell in row:
                    cell.stepToNextState()

    def clear(self):
        for row in self.cells:
            for cell in row:
                cell.displayState(Cell.Dead)

if __name__ == "__main__":
    frame = Frame(root)
    frame.pack()
    grid = Grid(frame,25,25)
    bottomFrame = Frame(root)
    bottomFrame.pack (side = BOTTOM)
    buttonStep = Button(bottomFrame , text="Step" , command=grid.step)
    buttonStep.pack(side = LEFT)
    buttonClear = Button(bottomFrame, text = "Clear", command=grid.clear)
    buttonClear.pack(side=LEFT , after=buttonStep)
    root.mainloop()

错误信息如下:
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python33\lib\tkinter\__init__.py", line 1442, in __call__
    return self.func(*args)
  File "C:\Users\Owner\Desktop\Other\Programs & Misc\Python\Tyler's Game of Life.py", line 65, in step
    cell.stepToNextState()
  File "C:\Users\Owner\Desktop\Other\Programs & Misc\Python\Tyler's Game of Life.py", line 27, in stepToNextState
    self.displayState(self.nextState)
AttributeError: 'Cell' object has no attribute 'nextState'

如果有人能指出错误出现的地方/导致错误的原因,并可能提供一种修复方法,我将不胜感激。

1
看起来您有很多缩进问题,而在Python中正确的缩进是至关重要的。这只是复制到SO时的错误吗? - Barmar
我已经缩进了你的问题,之后它就正常工作了... - Alok
1
@shaktimaan 如果他的问题是缩进方面的,不要在问题中进行更正 - 请将其作为答案发布。 - Barmar
@Barmar:我只是把问题进行了缩进,以便其他人能够理解并帮助解决问题。之后我运行了它,没想到这就是唯一的问题。 - Alok
好的,谢谢先生。我会记住的 :) - Alok
显示剩余2条评论
1个回答

2
问题似乎是你的for row in cells循环在之前的for x in range(0, self.sizex)循环内部。如果正确缩进,step方法应该像这样:
def step (self):
    cells = self.cells
    for x in range (0,self.sizex):
        if x==0: x_down = self.sizex-1
        else: x_down = x-1
        if x==self.sizex-1: x_up = 0
        else: x_up = x+1
        for y in range(0,self.sizey):
            if y==0: y_down = self.sizey-1
            else: Y_down = y-1
            if y==self.sizey-1: y_up = 0
            else: y_up = y+1
            sum = cells[x_down][y].state + cells[x_up][y].state + cells[x][y_down].state + cells[x][y_up].state + cells[x_down][y_down].state +cells[x_up][y_up].state + cells[x_down][y_up].state + cells[x_up][y_down].state
            cells[x][y].setNextState(sum)
    for row in cells:                     # unindent these
        for cell in row:                  # lines by one
            cell.stepToNextState()        # level each

如果所有缩进问题得到解决(或原始代码中没有这些问题),仍有一个问题可能在某些情况下会引起问题。该问题是Cell.setNextState方法无法处理每种情况。具体来说,如果细胞是活着的并且应该保持不变(它有两个或三个活着的邻居),则不设置nextState。你的ifelif语句链缺少else应该让我意识到这一点,但我第一次检查函数时忽略了它。
以下是修复方法:
def setNextState (self , Neighbours):
    if self.state == Cell.Live and (Neighbours < 2 or Neighbours > 3):
        self.nextState = Cell.Dead
    elif self.state == Cell.Dead and Neighbours == 3:
        self.nextState = Cell.Live
    else: # remove the conditions on this block, all the state changes were handled above
        self.nextState = self.state

尝试取消缩进后,我仍然收到相同的错误:'Cell'对象没有属性'nextState' - Chubzorz
@Chubzorz:我找到了剩下的问题并编辑了我的答案。 - Blckknght

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接