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解压成game1board1

【讨论】:

【参考方案2】:

return 语句的缩进

return g,b

使它成为你函数中else 的一部分。如果文件无法打开,则创建一个新游戏

g,b = creategame()

但永远不会归还它。因此,使用此函数返回的值的代码可能会引发错误。您应该取消缩进(如果有这样的词)return 语句,使其成为函数代码的一部分,而不是 else 分支

或者creategame() 可能返回 None 并且您的行 g,b = creategame() 会引发错误。

对于此类问题发布(和分析)回溯将帮助您更快地调试代码。

【讨论】:

我比你快一点=p

以上是关于python NoneType 对象不可迭代的主要内容,如果未能解决你的问题,请参考以下文章

Python - TypeError:“NoneType”对象不可迭代

面向对象:“NoneType”对象不可迭代。为啥?

运行测试时突然出现“TypeError:'NoneType'对象不可迭代

TypeError: 'NoneType' 对象不可迭代,使用带有 Selenium/Appium 的页面对象框架

TypeError:调用键函数时“NoneType”对象不可迭代

在执行并行 ssh 时获取“TypeError:'NoneType' 对象不可迭代”