Программирование аркадных игр и обучение информатике

Программирование аркадных игр
и обучение информатике

Chapter 18: Исключения

Видео: Обработка исключений

Исключения используются для обработки ненормальных условий, которые могут сложиться во время выполнения кода. Исключения зачастую используются при работе с сетью и файлами. Это позволяет коду элегантно справляться с нехваткой места на диске, сетевыми ошибками или ошибками с доступом к файлам.

18.1 Словарь

Есть несколько термином и фраз, используемых при работе с исключениями. Вот наиболее часто используемые:

18.2 Обработка исключений

Код обработки исключений достаточно прост. Ознакомьтесь с нижеприведённым примером:

# Деление на ноль
try:
    x = 5/0
except:
    print("Error dividing by zero")

На второй строке поставлено выражение try. Каждая ниже сдвинутая строка является частью “блока try.” Под ним не может быть несдвинутого кода, который не начинается с выражения except. Выражение try дефинирует отрывок кода, который программа постарается выполнить.

Если во время выполнения кода появляется исключение, то выполнение немедленно перейдёт в “блок catch.” Этот блок кода сдвинут под выражением except на 4й строке. Этот код ответственен за обработку ошибок.

Также, возможно ловить ошибки, происходящие во время преобразования текста в число:

# Неправильное преобразование
try:
    x = int("fred")
except:
    print ("Error converting fred to a number")

Исключение будет брошено на третьей строке, потому что “fred” не может быть представлен в целочисленном формате. Код на строке 5 выведет сообщение с ошибкой.

Ниже приведена расширенная версия этого примера. Она проверяет, действительно ли пользователь ввёл целое число. Код использует обработку исключений для поимки возможной ошибки при конвертации на строке 5. Код на шестой строке, ставящий numberEntered на True, не выполнится, если на пятой строке произошло исключение.

numberEntered=False
while numberEntered == False:
    numberString = input("Enter an integer: ")
    try:
        n = int(numberString)
        numberEntered = True
    except:
        print ("Error, invalid integer")

Файлы особенно уязвимы к ошибкам во время работы с ними. Диск может заполнится, пользователь может удалить используемый файл во время записи, файл могут переместить или USB диск может быть выбран во время операции. Эти типы ошибок также можно легко поймать с помощью обработки исключений.

# Ошибка при открытии файла
try:
    f = open('myfile.txt')
except:
    print("Error opening file")  

Несколько типов ошибок могут быть пойманы и обработаны по-разному. Это может быть полезным для предоставления более точных сообщений об ошибках пользователю, нежели “произошла ошибка.”

В нижеприведённом коде, несколько типов ошибок могут произойти на строчках 5-8. Размещая IOError после except на строке 9, только ошибки ввода / вывода будут обрабатываться этим кодом. Подобно этому, строка 11 обрабатывает только связанные с конвертацией ошибки, а строка 13 - ошибки, связанные с делением на ноль. Последняя обработка исключения происходит на 15й строке. Так как строка 15 не включает в себя особого типа ошибки, она обработает любую ошибку, не учтённую в ранее приведённых блоках except. Обработка except “поймать-всё” всегда должна быть последней.

Строка 1 импортирует библиотеку sys, которая используется на строке 16 для вывода случившейся ошибки.

import sys

# Несколько ошибок    
try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
    x = 101/i
except IOError:
    print ("Ошибка ввода/вывода")
except ValueError:
    print ("Не смог преобразовать данные в целое число.")
except ZeroDivisionError:
    print ("Ошибка при делении на ноль")
except:
    print ("Неожиданная ошибка:", sys.exc_info()[0])

Список встроенных исключений доступен по адресу:
http://docs.python.org/library/exceptions.html\#bltin-exceptions

18.3 Пример: сохранения рекордных очков

Это показывает, как сохранить рекордные очки между играми. Очки хранятся в файле под названием high_score.txt.

"""
Show how to use exceptions to save a high score for a game.

Sample Python/Pygame Programs
Simpson College Computer Science
http://programarcadegames.com/
http://simpson.edu/computer-science/
"""


def get_high_score():
    # Default high score
    high_score = 0

    # Try to read the high score from a file
    try:
        high_score_file = open("high_score.txt", "r")
        high_score = int(high_score_file.read())
        high_score_file.close()
        print("The high score is", high_score)
    except IOError:
        # Error reading file, no high score
        print("There is no high score yet.")
    except ValueError:
        # There's a file there, but we don't understand the number.
        print("I'm confused. Starting with no high score.")

    return high_score


def save_high_score(new_high_score):
    try:
        # Write the file to disk
        high_score_file = open("high_score.txt", "w")
        high_score_file.write(str(new_high_score))
        high_score_file.close()
    except IOError:
        # Hm, can't write it.
        print("Unable to save the high score.")


def main():
    """ Main program is here. """
    # Get the high score
    high_score = get_high_score()

    # Get the score from the current game
    current_score = 0
    try:
        # Ask the user for his/her score
        current_score = int(input("What is your score? "))
    except ValueError:
        # Error, can't turn what they typed into a number
        print("I don't understand what you typed.")

    # See if we have a new high score
    if current_score > high_score:
        # We do! Save to disk
        print("Yea! New high score!")
        save_high_score(current_score)
    else:
        print("Better luck next time.")

# Call the main function, start up the game
if __name__ == "__main__":
    main()

18.4 Объекты исключений

Подробная информация об ошибке может быть взята из объекта исключения. Этот объект может быть возвращён при поимке ошибки используя ключевое слово as. Например:

try:
	x=5/0
except ZeroDivisionError as e:
	print(e)

Переменная e указывает на дополнительную информацию об исключении, которую можно вывести. С объектами исключения можно сделать ещё больше, но, к сожалению это выходит за рамки этой главы.

18.5 Генерация исключений

Исключения могут генерировать с помощью команды raise. Например:

# Генерация исключений
def getInput():
    userInput = input("Введите что-нибудь: ")
    if len(userInput) == 0:
        raise IOError("Пользователь ничего не ввёл")
    
getInput()

Попробуйте взять вышеприведённый код и добавить в него обработку вызванного исключения IOError.

Возможно создать собственные исключения, но это выходит за рамки этой книги. Интересующийся читатель может узнать больше, пройдя по ссылке:
http://docs.python.org/tutorial/errors.html#raising-exceptions

18.6 Корректное использование исключений

Исключения не должны быть использованы тогда, когда условие if может обработать ошибку с такой же лёгкостью. Нормальный код не должен вызывать исключений во время следования “счастливому выполнению” программы. Хорошо построенный блок try/catch легко отслеживается. Отладка сложного кода, включающего в себя большое количество исключений и прыжков внутри кода может быть истинным кошмаром.

18.7 Проверка пройденного

Эти вопросы также могут быть скачаны в виде бланка:
[docx] [doc] [pdf]

  1. Дайте дефиниции следующим терминам:
    • Exception:
    • Exception Handling:
    • Try block:
    • Catch block:
    • Unhandled exception:
    • Throw:
  2. Покажите, как можно модифицировать следующий код так, чтобы в случае неудачного преобразования в число выводилась ошибка:
    user_input_string = input("Enter a number")
    user_value = int(user_input_string)
    
  3. Что выведет следующий код?
    x=5
    y=0
    print("A")
    try:
        print("B")
        a=x/y
        print("C")
    except:
        print("D")
    print ("E")
    print (a)
    
  4. 4. Что выведет следующий код?
    x=5
    y=10
    print("A")
    try:
        print("B")
        a=x/y
        print("C")
    except:
        print("D")
    print ("E")
    print (a)
    

You are not logged in. Log in here and track your progress.