2013-11-18 2 views
1

Этот код работает нормально, когда «filename» является файлом, который существует ... когда он этого не делает, но ... Я продолжаю получать ту же ошибку: ТипError: объект «NoneType» не является итерируемым (Errno 2)python NoneType object is not itable

Несмотря на то, что я никогда не перебираю что-либо, если файл не открывается в самом начале функции. Я много раз просматривал свой код и не могу найти, где бы я перебирал объект, который не является итерируемым.

NB. Я также пытался использовать «за исключением IOError», и получаю тот же результат.

Функция принимает только один аргумент, то его переменная "имя файла"

Taceback:

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 

NB. вызов функции осуществляется с помощью строки, которая собрана из пользовательского ввода «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 

Edit: Хах. Большое спасибо, я был настолько застрял в ошибке итерации, что даже не нашел этого, когда я потратил более часа, просматривая все, что может вызвать ошибку итерации.

Это была только идентификация оператора возврата.

+5

Не могли бы вы добавить трассировку? Как догадаться, что возвращает 'creategame()'? – RedBaron

+6

Публикация огромной горы кода - не очень хорошая идея. Можете ли вы определить, где (какая строка) возникает ошибка? – Raiyan

+1

Можете ли вы проверить, действительно ли вызывается 'except FileNotFoundError'? И я не думаю, что это 'FileNotFoundError', это должно быть' IOError'. Попробуйте изменить это и добавьте инструкцию печати внутри, чтобы узнать, вызвано ли это исключение. – justhalf

ответ

2

Я бы предположил, что проблема находится на последней строке, должна быть разделена (уменьшить отступ на один уровень). В вашем текущем коде, когда файл не найден, функция вернет None. И ваша ошибка NoneType может возникнуть в коде, используя вывод этой функции.

Попробуйте уменьшить отступ вашего оператора возврата.

EDIT:

Видя вашу отслеживающий этот вопрос подтверждается, что ошибка, так как он не может распаковать None в game1 и board1

2

Отступ оператора возврата

return g,b 

делает его частью функции else в вашей функции. Если файл не может быть открыт, вы создаете новую игру

g,b = creategame() 

но никогда не возвращение его. Поэтому, возможно, код, который потребляет значения, возвращаемые этой функцией, вызывает ошибку. Вы должны отменить отступ (если есть такое слово) return заявления, чтобы сделать его частью коды функции, а не else филиала

Или, может быть, creategame() возвращает None и ваша линия g,b = creategame() не вызывают ошибку.

Для таких вопросов, проводящих (и анализируя) трассировку, вы сможете быстрее отлаживать код.

+1

Я немного быстрее вас = p – justhalf