[英]Why is it returning TypeError: object of type 'NoneType' has no len()
Python 3.8.2 Mac Big Sur 11.2.1 Python 3.8.2 Mac 大苏尔 11.2.1
This code is supposed to be a simple minesweeper game in the terminal but when i run it i only get a error message (shown below) i couldn't find any help to this problem when searching around so i thought to ask it myself instead这段代码应该是终端中的一个简单的扫雷游戏,但是当我运行它时,我只收到一条错误消息(如下所示)我在搜索时找不到任何解决此问题的帮助,所以我想自己问一下
import random
import re
class Board:
def __init__(self, dim_size, num_bombs):
self.dim_size = dim_size
self.num_bombs = num_bombs
self.board = self.make_new_board()
self.assign_values_to_board
self.dug = set()
def make_new_board(self):
board = [[None for _ in range(self.dim_size)] for _ in range(self.dim_size)]
def assign_values_to_board(self):
for r in range(self.dim_size):
for c in range(self.dim_size):
if self.board[r][c] == '*':
continue
self.board[r][c] = self.get_num_neighboring_bombs(r, c)
def get_num_neighboring_bombs(self, row, col):
num_neighboring_bombs = 0
for r in range(max(0, row-1), min(self.dim_size-1, row+1)+1):
for c in range(max(0, col-1), min(self.dim_size - 1, col+1)+1):
if r == row and c == col:
continue
if self.board[r][c] == '*':
num_neighboring_bombs += 1
return num_neighboring_bombs
bombs_planted = 0
while bombs_planted < self.num_bombs:
loc = random.randint(0, self.dim_size**2 - 1)
row = loc // self.dim_size
col = loc % self.dim_size
if board [row][col] == '*':
# bomb already plated here
continue
board[row][col] = '*' # plant the bomb
bombs_planted += 1
return board
def dig(self, row, col):
self.dug.add((row, col))
if self.board[row][col] == '*':
return False
elif self.board[row][col] > 0:
return True
for r in range(max(0, row-1), min(self.dim_size-1, row+1)+1):
for c in range(max(0, col-1), min(self.dim_size - 1, col+1)+1):
if (r, c) in self.dug:
continue
self.dig(r, c)
return True
def __str__(self):
visible_board = [[None for _ in range(self.dim_size)] for _ in range(self.dim_size)]
for row in range(self.dim_size):
for col in range(self.dim_size):
if (row,col) in self.dug:
visible_board[row][col] = str(self.board[row][col])
else:
visible_board[row][col] = ' '
string_rep = ''
widths = []
for idx in range(self.dim_size):
columns = map(lambda x: x[idx], visible_board)
widths.append(
len(
max(columns, key = len)
)
)
indices = [i for i in range(self.dim_size)]
indices_row = ' '
cells = []
for idx, col in enumerate(indices):
format = '%-' + str(widths[idx]) + "s"
cells.append(format % (col))
indices_row += ' '.join(cells)
indices_row += ' \n'
for i in range(len(visible_board)):
row = visible_board[i]
string_rep += f'{i} |'
cells = []
for idx, col in enumerate(row):
format = '%-' + str(widths[idx]) + "s"
cells.append(format % (col))
string_rep += ' |'.join(cells)
string_rep += ' |\n'
str_len = int(len(string_rep) / self.dim_size)
string_rep = indices_row + '-'*str_len + '\n' + string_rep + '-'*str_len
return string_rep
def play(dim_size=10, num_bombs=10):
board = Board(dim_size, num_bombs)
safe = True
while len(board.dug) < board.dim_size ** 2 - num_bombs:
print(board)
user_input = re.split(',(\\s)*', input("Where would you like to dig? Input as row,col: "))
row, col = int(user_input[0]), int(user_input[-1])
if row < o or row >= board.dim_size or col < 0 or col >= dim_size:
print("Invalid location. Try again")
continue
safe = board.dig(row, col)
if not safe:
break
if safe:
print("Victory Royale!")
else:
print("You suck. Game Over")
board.dug = [(r,c) for r in range(board.dim_size) for c in range(board.dim_size)]
print(board)
if __name__ == '__main__':
play()
When i run this code it only returns当我运行此代码时,它只返回
Traceback (most recent call last):
File "/Users/henry/Documents/projects/GamesPython/Minesweeper/game.py", line 134, in <module>
play()
File "/Users/henry/Documents/projects/GamesPython/Minesweeper/game.py", line 115, in play
print(board)
File "/Users/henry/Documents/projects/GamesPython/Minesweeper/game.py", line 82, in __str__
max(columns, key = len)
TypeError: object of type 'NoneType' has no len()
How can i fix this problem我该如何解决这个问题
The iterable columns
has at least one None
value in it.可迭代columns
中至少有一个None
值。 Here is a simple example that provides the same error given the same line of code:这是一个简单的示例,它在给定相同的代码行的情况下提供相同的错误:
columns = [ "a", None, "b" ]
max(columns, key = len)
Result:结果:
max(columns, key = len)
TypeError: object of type 'NoneType' has no len()
As to why that None
value is in there, columns
is built from visible_board
.至于为什么None
值在那里, columns
是从visible_board
的。 I haven't spent the time to understand your logic completely, but I will point out that the line of code that builds visible_board
is very suspicious:我还没有花时间完全理解你的逻辑,但我会指出构建visible_board
的代码行非常可疑:
visible_board = [[None for _ in range(self.dim_size)] for _ in range(self.dim_size)]
Sure looks to me like it's going to build a list with a lot of None
entries in it.当然,在我看来,它会构建一个包含很多None
条目的列表。 That is verified when running your code in a debugger.在调试器中运行代码时会验证这一点。 At the point of the error, visible_board
looks like this:在出现错误时, visible_board
如下所示:
[[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '], [None, None, None, None, None, None, None, None, None, None], [None, None, None, None, None, None, None, None, None, None], [None, None, None, None, None, None, None, None, None, None], [None, None, None, None, None, None, None, None, None, None], [None, None, None, None, None, None, None, None, None, None], [None, None, None, None, None, None, None, None, None, None], [None, None, None, None, None, None, None, None, None, None], [None, None, None, None, None, None, None, None, None, None], [None, None, None, None, None, None, None, None, None, None]] [['','','','','','','','','',''],[无,无,无,无,无,无,无,无,无,无],[无,无,无,无,无,无,无,无,无,无],[无,无,无,无,无,无,无,无,无,无],[无,无,无,无,无,无,无,无,无,无],[无,无,无,无,无,无,无,无,无,无],[无,无,无,无,无,无,无,无,无,无],[无,无,无,无,无,无,无,无,无,无],[无,无,无,无,无,无,无,无,无,无],[无,无,无,无,无,无,无,无,无,无,无]]
So it isn't surprising that you end up trying to cal the len
attribute on a None
value and get the error that you do.因此,您最终尝试在None
值上调用len
属性并得到您所做的错误也就不足为奇了。
What seems to be happening here is that one of the variables you are passing to max()
is not defined (that is what NoneType
usually means -- something has no type (eg. it's a null
value), so you can't get the length of it).这里似乎发生的是,您传递给max()
的变量之一没有定义(这就是NoneType
通常的意思—— 某些东西没有类型(例如,它是一个null
值),所以你不能得到它的长度)。 Maybe you have forgotten to return
something from one of your functions, or perhaps there is a scope error you aren't expecting.也许您忘记了从您的某个函数中return
某些内容,或者可能出现了您未预料到的 scope 错误。 It's really hard to tell from your error stack because there are no line numbers in your code and you use max()
a bunch of times.从您的错误堆栈中很难分辨出来,因为您的代码中没有行号,并且您多次使用max()
。
This is pretty complicated, but not that "large," and you have divided your logic nicely into functions.这非常复杂,但不是那么“大”,并且您已经将逻辑很好地划分为函数。 My suggestion would be start writing some unit tests, and probably I'd use doctest for something like this.我的建议是开始编写一些单元测试,并且可能我会使用doctest来完成类似的事情。 That should help you narrow-down the problem.这应该可以帮助您缩小问题的范围。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.