Наследование и исключения
Долги за прошлый раз:
hasattr() и getattr()
__iter__()
__del__()
Наследование
Объектное планирование и ООП
ООП:
Характеристика |
Python3 |
Инкапсуляция (не сокрытие) |
Иерархия пространств имён |
Наследование |
Наследование + C3 MRO |
Полиморфизм |
«Из коробки», т. к. duck typing |
Проксирование?
Хранить родительский объект в виде поля, а все методы нового класса делать обёрткой вокруг методов родительского объекта.
TODO пример
Простое наследование
- Видимость и перегрузка методов
- Преобразование типов и создание новых объектов текущего типа:
type(self)(…)
super()
Защита полей от случайной перегрузки («__»)
Множественное наследование
- Проблема ромбовидного наследования:
- Что нужно:
- Монотонность C: [C, …, B, …, A] ⇒ D(...(C)...): [D, …, C, …, B, …, A]
- Соблюдение порядка объявления
- ⇒ Некоторые ситуации невозможны (слишком симметричные)
- MRO C3
TODO https://rhettinger.wordpress.com/2011/05/26/super-considered-super/ ?
Исключения
Исключения – это механизм управления вычислительным потоком, который завязан на разнесении по коду проверки свойств данных и обработки результатов этой проверки.
Синтаксическая ошибка 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
Д/З
TODO