Программирование аркадных игр
и обучение информатикеChapter 18: Исключения
Исключения используются для обработки ненормальных условий, которые могут сложиться во время выполнения кода. Исключения зачастую используются при работе с сетью и файлами. Это позволяет коду элегантно справляться с нехваткой места на диске, сетевыми ошибками или ошибками с доступом к файлам.
18.1 Словарь
Есть несколько термином и фраз, используемых при работе с исключениями. Вот наиболее часто используемые:
- Exception(Исключение): Это понятие может означать одну из двух вещей. Первая - условия, сформировавшиеся из-за ненормального выполнения программы. Или оно может ссылаться на объект, описывающий состояние данных. Каждое исключение имеет объект, хранящий информацию о нём.
- Exception handling(Обработка исключений): процесс работы с исключениями для нормализации хода программы.
- Catch block(блок catch) или exception block(блок exception): Код, который обрабатывает ненормальные условия, называется “поймавшим” исключение.
- Throw или raise: В момент, когда было обнаружено ненормальное условие в работе программы, создаётся инстанция объекта исключения. Затем исключение “выкинуто(thrown)” или “(вызвано)raised” в коде для его поимки.
- Unhandled exception(необработанное исключение) или Uncaught exception(непойманное исключение): Исключение, которое было выкинуто, но никогда не поймано. Обычный этому исход будет ошибка с последующим закрытием программы.
- Try block(блок try): Набор кода, внутри которого может возникнуть исключение.
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]
- Дайте дефиниции следующим терминам:
- Exception:
- Exception Handling:
- Try block:
- Catch block:
- Unhandled exception:
- Throw:
- Покажите, как можно модифицировать следующий код так, чтобы в случае неудачного преобразования в число выводилась ошибка:
user_input_string = input("Enter a number") user_value = int(user_input_string)
- Что выведет следующий код?
x=5 y=0 print("A") try: print("B") a=x/y print("C") except: print("D") print ("E") print (a)
- 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.
English version by Paul Vincent Craven
Spanish version by Antonio Rodríguez Verdugo
Russian version by Vladimir Slav
Turkish version by Güray Yildirim
Portuguese version by Armando Marques Sobrinho and Tati Carvalho
Dutch version by Frank Waegeman
Hungarian version by Nagy Attila
Finnish version by Jouko Järvenpää
French version by Franco Rossi
Korean version by Kim Zeung-Il
Chinese version by Kai Lin