UnboundLocalError при попытке открыть неверное имя файла - PullRequest
0 голосов
/ 09 ноября 2019

Я написал программу, которая принимает имя файла и возвращает числа, и она работает, как и ожидалось, когда имя файла вводится правильно, но когда я пытаюсь преднамеренно написать неправильное имя файла, вместо того, чтобы выдавать «ошибку: файл ненайден "из исключения, он скажет:

def getFile(fileName):
lines = []
try:
    infile = open(fileName, 'r')
    if infile != None:
        for line in infile:
         lines.append(line)

except IOError:
    print('Error: file not found.')

finally:
    infile.close()
return lines

1 Ответ

1 голос
/ 09 ноября 2019

Если исключение вызвано open, локальная переменная infile никогда не объявляется, не говоря уже о присвоении, поэтому попытка вызова infile.close() в блоке finally вызовет UnboundLocalError как вы видите здесь. Вы можете несколько «исправить» это, объявив infile с каким-то специальным неинициализированным значением (например, None) и явно проверив его следующим образом:

def getFile(fileName):
    lines = []
    infile = None
    try:
        infile = open(fileName, 'r')
        for line in infile:
            lines.append(line)
    except IOError:
        print('Error: file not found.')
    finally:
        if infile is not None:
            infile.close()
    return lines

В качестве альтернативы, поскольку файловые объекты являются менеджерами контекста , вы можете написать что-то вроде:

def getFile(fileName):
    lines = []
    try:
        with open(fileName, 'r') as infile:
            for line in infile:
                lines.append(line)
    except IOError:
        print('Error: file not found.')
    return lines

... что обеспечит закрытие infile в более синтаксически краткой и структурированной манере.


Обратите внимание, что наошибка open вызывает OSError (например, FileNotFoundError) вместо возврата None, поэтому ваш существующий чек является избыточным.

Кроме того, IOError может быть вызвано при итерации файла, а не при его первоначальном открытии, поэтому распечатанное сообщение об ошибке может быть неправильным в этих обстоятельствах.

Наконец, поскольку infile являетсяитерируемый, вы можете итеративно построить список из него, легко используя конструктор , который принимает итеративно напрямую , например:

return list(infile)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...