属性错误:对象没有属性 Python
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22827804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Attribute error: Object has no attribute Python
提问by Chubzorz
I am trying to program a version of conway's game of life however I keep getting the message 'Cell' Object Has no attribute 'nextState'
when it seems like it should declare the value of nextState before asking to reference it. here is my code:
我正在尝试编写一个版本的康威生活游戏,但是'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()
The error message is:
错误信息是:
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'
If anyone could point out where the error is occuring / what is causing it and possibly a way to fix it I would be very grateful.
如果有人能指出错误发生的位置/导致错误的原因以及可能的解决方法,我将不胜感激。
采纳答案by Blckknght
The issue appears to be that your for row in cells
loop is inside of your previous for x in range(0, self.sizex)
loop. Here's what the step
method should look like if you get it correctly indented:
问题似乎是您的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
If all the indentation issues are taken care of (or were not in the original code), there's still an issue that maycause an issue in certain situations. The issue is that the Cell.setNextState
method doesn't handle every situation. Specifically, it doesn't set nextState
if a cell is alive and should stay so (it has two or three living neighbors). The lack of an else
on your chain of if
and elif
statements should have raised this as a red flag for me, but I overlooked it the first time I examined the function.
如果所有缩进问题都得到处理(或不在原始代码中),那么在某些情况下仍然存在可能导致问题的问题。问题是该Cell.setNextState
方法不能处理所有情况。具体来说,它不会设置nextState
一个单元格是否活着并且应该保持这样(它有两个或三个活着的邻居)。else
你的if
andelif
语句链上缺少 an对我来说应该是一个危险信号,但我第一次检查该函数时忽略了它。
Here's how it can be fixed:
以下是修复方法:
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