问题描述
我用 python
(在 jupyter notebook
中,我用了十个)做了一个深度学习数字猜测器,当我运行代码时,它应该打开一个空窗口(用 pygame
),我可以画数字来训练深度学习,但我得到了 AttributeErrors
这是我的代码:
import tensorflow as tf
import pygame
import matplotlib.pyplot as plt
import numpy as np
from tkinter import *
from tkinter import messageBox
class pixel(object):
def __init__(self,x,y,width,height):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = (255,2555,255)
self.neighbors = []
def draw(self,surface):
pygame.draw.rect(surface,self.color,(self.x,self.y,self.x + self.width,self.y + self.height))
def getNeighbors(self,g):
j = self.x // 20
i = self.y // 20
rows = 28
cols = 28
if i < cols -1:
self.neighbors.append(g.pixels[i + 1][j])
if i > 0:
self.neighbors.append(g.pixels[i - 1][j])
if j < rows -1:
self.neighbors.append(g.pixels[i][j + 1])
if j > 0:
self.neighbors.append(g.pixels[i - 1][j + 1])
if j > 0 and i > 0:
self.neighbors.append(g.pixels[i - 1][j - 1])
if j + 1 < rows and i > -1 and i - 1 > 0:
self.neighbors.append(g.pixels[i - 1][j + 1])
if j - 1 < rows and i < cols - 1 and j - 1 > 0:
self.neighbors.append(g.pixels[i + 1][j - 1])
if j < rows - 1 and i < cols - 1:
self.neighbors.append(g.pixels[i + 1][j + 1])
class grid(object):
pixels = []
def __init__(self,row,col,height):
self.rows = row
self.cols = col
self.len = row * col
self.width = width
self.height = height
self.generatePixels
pass
def draw(self,surface):
for row in self.pixels:
for col in row:
col.draw(surface)
def generatePixels(self):
x_gap = self.width // self.cols
y_gap = self.height // self.rows
self.pixels = []
for r in range(self.rows):
self.pixels.append([])
for c in range(self.cols):
self.pixels[r].append(pixel(x_gap * c,y_gap * r,x_gap,y_gap))
for r in range(self.rows):
for c in range(self.cols):
self.pixels[r][c].getNeighbors(self)
def clicked(self,pos):
try:
t = pos[0]
w = pos[1]
g1 = int(t) // self.pixels[0][0].width
g1 = int(t) // self.pixels[0][0].width
g2 = int(w) // self.pixels[0][0].height
return self.pixels[g2][g1]
except:
pass
def convert_binary(self):
li = self.pixels
newMatrix = [[] for x in range(len(li))]
for i in range(len(li)):
for j in range(len(li[i])):
if li[i][j].color == (255,225,255):
newMatrix[i].append(0)
else:
newMatrix[i].append(1)
mnist = tf.keras.datasets.mnist
(x_train,y_train),(x_test,y_test) = mnist.load_data()
x_test = tf.keras.utils.normalize(x_test,axis=1)
for row in range(28):
for x in range(28):
x_test[0][row][x] = newMatrix[row][x]
return x_test[:1]
def guess(li):
model = tf.keras.models.load_model('m.model')
predictions = model.predict(li)
print(predictions[0])
t = (np.argmax(predictions[0]))
print("I predict this number is a:",t)
window = Tk()
window = withdraw()
messageBox.showinfow("prediction","I predict this number is a:" + str(t))
#plt.imshow(li[0],cmap=plt.cm.binary)
#pit.show()
def main():
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
li = g.convert_binary()
guess(li)
g.generatePixels()
if pygame.mouse.get_pressed()[0]:
pos = pygame.mouse.get_pos()
clicked = g.clicked(pos)
clicked.color = (0,0)
for n in clicked.neighbors:
n.color = (0,0)
if pygame.mouse.get_pressed()[2]:
try:
pos = pygame.mouse.get_pos()
clicked = g.clicked(pos)
clicked.color = (255,255,255)
except:
pass
g.draw(win)
pygame.display.update()
pygame.init()
width = height = 560
win = pygame.display.set_mode((width,height))
pygame.display.set_caption("Number Guesser")
g = grid(28,28,height)
main()
这是输出:
pygame 2.0.1 (SDL 2.0.14,Python 3.8.8)
Hello from the pygame community. https://www.pygame.org/contribute.html
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-1-a4fa9a8a2b5c> in <module>
149 pygame.display.set_caption("Number Guesser")
150 g = grid(28,height)
--> 151 main()
<ipython-input-1-a4fa9a8a2b5c> in main()
129 pos = pygame.mouse.get_pos()
130 clicked = g.clicked(pos)
--> 131 clicked.color = (0,0)
132 for n in clicked.neighbors:
133 n.color = (0,0)
AttributeError: 'nonetype' object has no attribute 'color'
解决方法
-
g.clicked()
在访问返回值时显然会返回 None 以获取NoneType
对象错误。 - 如果我们查看
clicked()
方法,我们可以看到有一个try: ... except: pass
构造。这意味着可能发生的任何和所有错误都被抛出窗口,并且由于未显式返回的函数返回None
,我们可以假设这就是发生的事情。- 要点 1:永远不要,永远像那样使用
try: except:
。只需让异常发生并在其他地方处理即可。
- 要点 1:永远不要,永远像那样使用
- 在该函数中可能存在我们不知道的某些异常的原因可能是例如
- 解包参数时的
IndexError
- 一个
IndexError
访问self.pixels
- a
ZeroDivisionError
-
NameError
或AttributeError
(如果我们输入错误) - 还有其他任何事情,如果我们知道的话
- 解包参数时的
- 暂时,让我们看看初始化
self.pixels
的内容...看起来generatePixels
就是这样。 - 什么叫
generatePixels
?嗯……没什么,因为grid
的__init__
中的“调用”缺少调用括号:self.generatePixels
应该是self.generatePixels()
。- 要点 2:使用 IDE 或 linter 来警告您类似的事情。
所以,追溯:
-
self.pixels
永远不会被初始化,因为generatePixels
没有被调用。 - 访问
self.pixels
的异常被裸except:
吞掉。 - 您从
None
函数获得clicked()
。 - 您尝试访问
None
并获得异常。
虽然代码中还有其他明显的问题,但您可能希望从
- 修复对
generatePixels()
的调用 - 解包
try: except:
s