Исключения
Долги за прошлую лекцию
Проблемы порядка поиска методов (MRO)
В Java, кажется, нет множественного наследования
- Ромбическое наследование: обход графа вглубь приводит к неправильному порядку поиска
- Неравнодлинное наследование; обход графа вширь приводит к неправильному порядку поиска
⇒ Нужна линеаризация
Python3: C3-линеаризация, т. е. превращение графа в список
- монотонность (порядок классов потомка такой же, как у родителей)
- соблюдение порядка объявления
- ⇒ неоднозначные ситуации запрещены
method resolution order в Python3
поле класса __mro__
super()
Вместо ссылки на заранее известный родительский класс изготовим прокси-объект super()
super() возвращает не какой-то из родительских классов, а прокси-объект, в котором сообразно MRO доступны поля родительских объектов
super() — super(класс, объект) (а где self ?? @-- FrBrGeorge 2017-12-01 16:26:02@ )
Исключения
Исключения – это механизм управления вычислительным потоком, который завязан на разнесении по коду проверки свойств данных и обработки результатов этой проверки.
Синтаксическая ошибка SyntaxError — не обрабатывается (ещё такие ошибки?)
Оператор try:
Клауза except
Вариант except Исключение
Исключения — объекты Python3 (унаследованы от BaseException)
- Дерево исключений, перехват всех дочерних
Вариант except Исключение as идентификатор, произвольные параметры исключения
Клауза else: — если исключений не было
Клауза finally: — выполняется даже если исключение не перехвачено
Оператор raise
Собственные исключения (унаследованиы от Exception, а не BaseException — некоторые исключения перехватывать не стоит)
вариант raise Exception vs. raise Exception(параметры) — по идее Exception — это класс, а Exception() — объект, но на самом деле при выхове исключения всё равно изготавливается объект
Исключения — не «ошибки», а способ обработки некоторых условий не так, где они были обнаружены.
Пример:
1 class Exc1(Exception): pass
2 class Exc2(Exception): pass
3
4 def funerr(a,b):
5 if a<b:
6 raise Exc1("A must be greater than B")
7 return a//b
8
9 def justfun(a,b):
10 if a<b:
11 raise Exc2("A must be greater than B")
12 c = funerr(2*a, 3*b)
13 return c
14
15 for a,b in (10,3),(5,5),(10,0):
16 try:
17 c = justfun(a,b)
18 except Exc1:
19 c = -1
20 except Exc2:
21 c = -2
22 except ZeroDivisionError:
23 c = -3
24 print(c)
Исключения порождаются в разных местах, а обрабатываются в одном:
2 -1 -3
Д/З
- Прочитать
про C3 в Википедии, на сайте Python
Про super() в статье Раймонда Хеттингера и документации
про исключения в учебнике
EJudge: BoldCalc 'Надёжный калькулятор'
Написать программу — калькулятор с переменными и обработкой ошибок
- Команда, начинающаяся на '#' — комментарий
Команда вида Переменная=выражение задаёт переменную
Команда вида выражение выводит значение выражения.
- Если команда содержит знак "=", но не является присваиванием, выводится диагностика "invalid assignment" (см. пример)
- Если слева от "=" находится не идентификатор, выводится диагностика "invalid identifier (см. пример)"
- В случае любых других ошибок выводится текст ошибки.
«Выражение» — это произвольное выражение Python3, в котором вдобавок можно использовать уже определённые переменные (и только их). Пробелов в командах нет. Пустая команда означает конец вычислений. Калькулятор вводит и исполняет команды по одной, тут же выводя диагностику, но в тестах это выглядит как ввод последовательности строк и вывод последовательности строк.
42 100500//33 "Qq!"*(6-2) # Здесь ошибка 3,,5 10/(8-8) "wer"[2]+"qwe"[1] "wer"[7]+"qwe"[9] 1+(2+(3 a0=5 b0=7 # И здесь ошибка 12N=12 # И ещё где-то были a0+b0*8 c=b0//2+a0 d==100 c+d sorted(dir())
42 3045 Qq!Qq!Qq!Qq! invalid syntax (<string>, line 1) division by zero rw string index out of range unexpected EOF while parsing (<string>, line 1) invalid identifier '12N' 61 invalid assignment 'd==100' name 'd' is not defined ['__builtins__', 'a0', 'b0', 'c']
TODO