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

时间:2014-04-03 04:21:50

标签: python tkinter attributeerror conways-game-of-life

我正在尝试编写康威生命游戏的一个版本,但是当我要求引用它时它似乎应该声明nextState的值时,我会继续收到消息'Cell' Object Has no attribute '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 个答案:

答案 0 :(得分:1)

问题似乎是您的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如果一个单元格是活着的并且应该保持这样(它有两个或三个活着的邻居)。您的elseif语句链上缺少elif应该将此作为我的红旗,但我第一次检查该功能时忽略了它。

以下是如何解决的问题:

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