python - 为什么返回 TypeError:“NoneType”类型的对象没有 len()
问题描述
Python 3.8.2 Mac 大苏尔 11.2.1
这段代码应该是终端中的一个简单的扫雷游戏,但是当我运行它时,我只收到一条错误消息(如下所示)我在四处搜索时找不到解决这个问题的任何帮助,所以我想自己问一下
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()
当我运行此代码时,它只返回
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()
我该如何解决这个问题
解决方案
可迭代对象columns
中至少有一个None
值。这是一个简单的示例,它在给定相同的代码行的情况下提供相同的错误:
columns = [ "a", None, "b" ]
max(columns, key = len)
结果:
max(columns, key = len)
TypeError: object of type 'NoneType' has no len()
至于为什么该None
值在那里,columns
是从visible_board
. 我没有花时间完全理解你的逻辑,但我会指出构建的代码行visible_board
非常可疑:
visible_board = [[None for _ in range(self.dim_size)] for _ in range(self.dim_size)]
当然在我看来它会建立一个包含很多None
条目的列表。在调试器中运行代码时会验证这一点。在发生错误时,visible_board
如下所示:
[['','','','','','','','','',''],[无,无,无,无,无,无,无,无,无,无],[无,无,无,无,无,无,无,无,无,无],[无,无,无,无,无,无,无,无,无,无],[无,无,无,无,无,无,无,无,无,无],[无,无,无,无,无,无,无,无,无,无],[无,无,无,无,无,无,无,无,无,无],[无,无,无,无,无,无,无,无,无,无,无],[无,无,无,无,无,无,无,无,无,无,无],[无,无,无,无,无,无,无,无,无,无,无]]
len
因此,您最终尝试在一个值上调用属性None
并得到您所做的错误也就不足为奇了。
推荐阅读
- java - 如何使用 dropbox api 解决 Spring Boot 中的多部分异常?
- elixir - mix.exs 文件中的 Elixir 版本要求无效
- java - 具有任何深度的嵌套项目的 Recyclerview
- python - 使用 Python 执行动态 SQL 但收到异常
- python - Kivy - 如果满足条件,如何更改每个文本输入的颜色
- c# - ASP.NET Core MVC/WebAPI 身份验证方案加匿名
- gerrit - 如何使用新补丁集在 Gerrit 中保留批准
- c++ - 使用 boost 套接字禁用 TIME_WAIT
- python - 如何找到 DBSCAN 的最佳参数?
- python-3.x - 尝试使用 tkinter gui 停止 Python 语音识别循环