python NoneType 对象不可迭代
Posted
技术标签:
【中文标题】python NoneType 对象不可迭代【英文标题】:python NoneType object is not iterable 【发布时间】:2013-12-01 04:52:49 【问题描述】:当“文件名”是一个存在的文件时,此代码运行良好......但是,当它不存在时...... 我不断收到同样的错误: TypeError: 'NoneType' 对象不可迭代 (Errno 2)
即使我从不迭代任何东西,除非在函数一开始就打开文件。我已经多次查看我的代码,但找不到在哪里迭代不可迭代的对象。
注意。我也尝试过“除了 IOError”,得到了相同的结果。
该函数只接受一个参数,即变量“文件名”
回溯:
Traceback (most recent call last):
File "C:\Users\Saume\Workspace\Chess\src\Main.py", line 431, in <module>
game1, board1 = loadgame(inp_f)
TypeError: 'NoneType' object is not iterable
注意。对函数的调用是使用从用户输入“inp_f”中收集的字符串完成的(loadgame 是函数的名称)
代码如下:
try:
f = open(filename, "r")
file_empty = False
except FileNotFoundError:
file_empty = True
# file doesn't exist, error string
if file_empty: # empty save file, create a new game
g, b = creategame() # this function works 100%... no problems here
else:
# amount of each pieces
tb = 0
tn = 0
cb = 0
cn = 0
fb = 0
fn = 0
db = 0
dn = 0
rb = 0
rn = 0
pb = 0
pn = 0
d = # dictionnary for the board
n = 0
f_game = ""
f_pieces = []
for line in f: # iterate on the file... only if file_empty == False....
if n == 0: # first line contains general game info
f_game = line
else: # other lines contain coordinates of the pieces
f_pieces += [line]
n += 1 # increment number of lines... n-1 == number of pieces
f.close() # close the file... only if the file was opened...
# validating the format of the first line
try:
temp1 = int(f_game[0])
temp2 = int(f_game[2])
temp3 = int(f_game[4])
temp4 = int(f_game[6])
temp5 = int(f_game[8])
f_game = [temp1, None, temp2, None, temp3, None, temp4, None, temp5]
except ValueError:
pass # display error message... bad format
for i in f_pieces: # iterate on the list that contains information about pieces
try:
i1 = int(i[0])
i2 = int(i[1])
except ValueError: # bad coordinates... piece is put outside the board
i1 = 8
i2 = 8
if i[2] == "T": # rook
if i[3] == "B": # white
if f_game[2] != 0 and i1 == 0 and i2 == 7: # short white roc is possible... this is the right rook, too
did_first_move = False
elif f_game[4] != 0 and i1 == 0 and i2 == 0: # long white roc is possible... and this is the right rook, too
did_first_move = False
else: # it is not one a rook implied ina possible roc
did_first_move = True
tb += 1 # increment the amount of this piece by 1
globals()["tb" + str(tb)] = Rook.Rook(0, i1, i2, did_first_move) # from the import Rook... which contains class Rook with its initializer that takes 4 args (color, line, column, first_move)
if i1 < 8 and i2 < 8: # if the coordinates are valid...
d[(i1, i2)] = globals()["tb" + str(tb)] # add it to the board dictionary... key is a tuple... element is a Piece.Piece class
else: # black...Rook still
if f_game[6] != 0 and i1 == 7 and i2 == 7: # short black roc possible... this is the right rook, too
did_first_move = False
elif f_game[8] != 0 and i1 == 7 and i2 == 0: # long black roc possible... this is the right rook, too
did_first_move = False
else: # the rook is not implied in a possible roc
did_first_move = True
tn += 1 # increment piece type
globals()["tn" + str(tn)] = Rook.Rook(1, i1, i2, did_first_move) # once again... from the import that takes 4 args
if i1 < 8 and i2 < 8: # if the coordinates are valid...
d[(i1, i2)] = globals()["tn" + str(tn)] # put it in the board dictionary
elif i[2] == "C": # Knight
if i[3] == "B": # white
cb += 1 # increment
globals()["cb" + str(cb)] = Knight.Knight(0, i1, i2) # from the import... not it takes 3 or 4 args... the last one being optional... as wether a Knight did their first move of not is irrelevant... it is not needed to pass a 4th arg
if i1 < 8 and i2 < 8: # if the coordinates are valid...
d[(i1, i2)] = globals()["cb" + str(cb)] # put it in the board dictionary
else: # black
cn += 1 # increment
globals()["cn" + str(cn)] = Knight.Knight(1, i1, i2) # create class instance from import...
if i1 < 8 and i2 < 8: # if the coordinates are valid...
d[(i1, i2)] = globals()["cn" + str(cn)] # put it in the board dictionary
elif i[2] == "F": # Bishop
if i[3] == "B": # white
fb += 1 # increment
globals()["fb" + str(fb)] = Bishop.Bishop(0, i1, i2) # create class instance from import...
if i1 < 8 and i2 < 8: # if the coordinates are valid...
d[(i1, i2)] = globals()["fb" + str(fb)] # put it in the board dictionary
else: # black
fn += 1 # increment
globals()["fn" + str(fn)] = Fou.Fou(1, i1, i2) # create class instance from import...
if i1 < 8 and i2 < 8: # if the coordinates are valid...
d[(i1, i2)] = globals()["fn" + str(fn)] # put it inside the board dictionary
elif i[2] == "D": # Queen
if i[3] == "B": # white
db += 1 # increment
globals()["db" + str(db)] = Queen.Queen(0, i1, i2) # create class instance from import...
if i1 < 8 and i2 < 8: # if coordinates are valid...
d[(i1, i2)] = globals()["db" + str(db)] # put it in the board dictionary
else: # black
dn += 1 # increment
globals()["dn" + str(dn)] = Queen.Queen(1, i1, i2) # create class instance from import...
if i1 < 8 and i2 < 8: # if the coordinates are valid...
d[(i1, i2)] = globals()["dn" + str(dn)] # put it inside the board dictionary
elif i[2] == "R": # King
if i[3] == "B": # white
if f_game[2] != 0 or f_game[4] != 0: # white king did not perform its first move
did_first_move = False
else: # white king did move
did_first_move = True
rb += 1 # increment
globals()["rb" + str(rb)] = King.King(0, i1, i2, did_first_move) # create class instance from the import...
pos_r0 = (i1, i2)
if i1 < 8 and i2 < 8: # if coordinates are valid...
d[(i1, i2)] = globals()["rb" + str(rb)] # put it inside the board dictionary
else: # black
if f_game[6] != 0 or f_game[8] != 0: # black king did not perform its first move
did_first_move = False
else: # black king did move
first = True
rn += 1 # increment
globals()["rn" + str(rn)] = King.King(1, i1, i2, did_first_move) # create class instance from import...
pos_r1 = (i1, i2)
if i1 < 8 and i2 < 8: # if the coordinates are valid...
d[(i1, i2)] = globals()["rn" + str(rn)] # put it in the board dictionary
else: # pawn
if i[3] == "B": # white
if i1 == 1: # the pawn is still at its starting position
did_first_move = False
else: # the pawn moved from its starting position
did_first_move = True
pb += 1 # increment
globals()["pb" + str(pb)] = Pawn.Pawn(0, i1, i2, did_first_move) # create class instance from import
if i1 < 8 and i2 < 8: # if coordinates are valid...
d[(i1, i2)] = globals()["pb" + str(pb)] # put it in the board dictionary
else: # black
if i1 == 1: # the pawn is still at its starting position
did_first_move = False
else: # the pawn moved from its starting position
did_first_move = True
pn += 1 # increment
globals()["pn" + str(pn)] = Pawn.Pawn(0, i1, i2, prem_depl) # create class instance from import...
if i1 < 8 and i2 < 8: # if coordinates are valid...
d[(i1, i2)] = globals()["pn" + str(pn)] # put it in the board dictionary
# create the board class instance from import... which only takes 1 arg... the board itself (dict)
b = Board.Board(d)
# create the game (GameManagement class instance... from import)
# it takes 3 optional args... number of turns since the start of the game, position of white king and position of black king...
g = GameManagement.GameManagement(f_game[0], pos_r0, pos_r1)
return g, b
编辑:哈。非常感谢,当我花了一个多小时查看可能导致迭代错误的所有内容时,我什至没有发现迭代错误。
这只是返回语句的标识。
【问题讨论】:
可以添加回溯吗?预感creategame()
会返回什么?
发布一大堆代码并不是一个好主意。您能否确定错误发生的位置(哪一行)?
你能检查一下except FileNotFoundError
是否真的被调用了?而且我认为不是FileNotFoundError
,应该是IOError
。尝试更改它并在里面添加一个打印语句,以查看是否调用了异常。
而且显然错误在最后一行,哈哈
【参考方案1】:
我猜问题出在最后一行,应该是缩进(将缩进减少一级)。在您当前的代码中,当找不到文件时,该函数将返回None
。并且您的NoneType
错误可能会出现在使用此函数输出的代码上。
尝试减少你的 return 语句的缩进。
编辑:
看到你的回溯,这个问题被确认是错误,因为它无法将None
解压成game1
和board1
【讨论】:
【参考方案2】:return 语句的缩进
return g,b
使它成为你函数中else
的一部分。如果文件无法打开,则创建一个新游戏
g,b = creategame()
但永远不会归还它。因此,使用此函数返回的值的代码可能会引发错误。您应该取消缩进(如果有这样的词)return
语句,使其成为函数代码的一部分,而不是 else
分支
或者creategame()
可能返回 None 并且您的行 g,b = creategame()
会引发错误。
对于此类问题发布(和分析)回溯将帮助您更快地调试代码。
【讨论】:
我比你快一点=p以上是关于python NoneType 对象不可迭代的主要内容,如果未能解决你的问题,请参考以下文章
Python - TypeError:“NoneType”对象不可迭代
运行测试时突然出现“TypeError:'NoneType'对象不可迭代
TypeError: 'NoneType' 对象不可迭代,使用带有 Selenium/Appium 的页面对象框架