Similar presentations:
exceptions
1.
ИсключенияДокладчик: Евграфов Михаил
2.
Исключения2
3.
Примеры исключений# пример синтаксической ошибки
num = 5
if num % 2 == 1 print("number is odd")
...
SyntaxError: invalid syntax
# пример логической ошибки
division = num / 0
...
ZeroDivisionError: division by zero
3
4.
Иерархия исключенийKeyboardInterrupt
SystemExit
BaseException
Exception
GeneratorExit
BaseExceptionGroup
4
5.
Иерархия исключенийKeyboardInterrupt
SystemExit
BaseException
Exception
GeneratorExit
BaseExceptionGroup
5
6.
try-exceptwhile True:
try:
...
...
except:
...
...
try-блок
except-блок /
обработчик ошибок
6
7.
Отсутствие исключения# input -> 5
try:
input_value = input("Enter a number: ")
number = int(input_value)
result = 10 / number
print(f"{result = }")
except ValueError:
print(f"input is invalid: {input_value}")
7
8.
Отсутствие исключения# input -> 5
try:
input_value = input("Enter a number: ")
number = int(input_value) # OK
result = 10 / number # OK
print(f"{result = }")
except ValueError:
print(f"input is invalid: {input_value}")
8
9.
Отсутствие исключения# input -> 5
try:
input_value = input("Enter a number: ")
number = int(input_value) # OK
result = 10 / number # OK
print(f"{result = }")
except ValueError:
print(f"input is invalid: {input_value}")
# result = 2.0
9
10.
Обрабатываемое исключение# input -> "string"
try:
input_value = input("Enter a number: ")
number = int(input_value) # ValueError
result = 10 / number
print(f"{result = }")
except ValueError:
print(f"input is invalid: {input_value}")
10
11.
Обрабатываемое исключение# input -> "string"
try:
input_value = input("Enter a number: ")
number = int(input_value) # ValueError
result = 10 / number
print(f"{result = }")
except ValueError: # совпадение
print(f"input is invalid: {input_value}")
# input is invalid: string
11
12.
Обрабатываемое исключение# input -> "string"
try:
input_value = input("Enter a number: ")
number = int(input_value) # ValueError
result = 10 / number
print(f"{result = }")
except ValueError: # совпадение
print(f"input is invalid: {input_value}")
# input is invalid: string
12
13.
Непойманное исключение# input -> 0
try:
input_value = input("Enter a number: ")
number = int(input_value) # OK
result = 10 / number
print(f"{result = }")
except ValueError:
print(f"input is invalid: {input_value}")
13
14.
Непойманное исключение# input -> 0
try:
input_value = input("Enter a number: ")
number = int(input_value) # OK
result = 10 / number # ZeroDivisionError
print(f"{result = }")
except ValueError: # несовпадение
print(f"input is invalid: {input_value}")
...
ZeroDivisionError: division by zero
14
15.
Общий обработчик# input -> "five"
try:
input_value = input("Enter a number: ")
number = int(input_value) # ValueError
result = 10 / number
print(f"{result = }")
except (ValueError, ZeroDivisionError):
print(f"input is invalid: {input_value}")
# input is invalid: five
15
16.
Общий обработчик# input -> 0
try:
input_value = input("Enter a number: ")
number = int(input_value)
result = 10 / number # ZeroDivisionError
print(f"{result = }")
except (ValueError, ZeroDivisionError):
print(f"input is invalid: {input_value}")
# input is invalid: 0
16
17.
Несколько обработчиков# input -> "five"
try:
input_value = input("Enter a number: ")
number = int(input_value) # ValueError
result = 10 / number
print(f"{result = }")
except ValueError:
print(f"input is invalid: {input_value}")
except ZeroDivisionError:
print("0 as input is forbidden")
# input is invalid: five
17
18.
Несколько обработчиков# input -> 0
try:
input_value = input("Enter a number: ")
number = int(input_value)
result = 10 / number # ZeroDivisionError
print(f"{result = }")
except ValueError:
print(f"input is invalid: {input_value}")
except ZeroDivisionError:
print("0 as input is forbidden")
# 0 as input is forbidden
18
19.
Порядок выбора обработчика# input -> "five"
try:
input_value = input("Enter a number: ")
number = int(input_value) # ValueError
result = 10 / number
print(f"{result = }")
except ValueError: # обрабатывает только ValueError
print(f"input is invalid: {input_value}")
except Exception as exc: # обрабатывает "все"
print(f"general handler got {type(exc).__name__}")
# input is invalid: five
19
20.
Порядок выбора обработчика# input -> 0
try:
input_value = input("Enter a number: ")
number = int(input_value) # OK
result = 10 / number # ZeroDivisionError
print(f"{result = }")
except ValueError: # обрабатывает только ValueError
print(f"input is invalid: {input_value}")
except Exception as exc: # обрабатывает "все"
print(f"general handler got {type(exc).__name__}")
# general handler got ZeroDivisionError
20
21.
Неверный порядок обработчиков# input -> "five"
try:
input_value = input("Enter a number: ")
number = int(input_value) # ValueError
result = 10 / number
print(f"{result = }")
except Exception as exc:
print(f"general handler got {type(exc).__name__}")
except ValueError:
print(f"input is invalid: {input_value}")
# general handler got ValueError
21
22.
try-except-else# input -> "five"
try:
input_value = input("Enter a number: ")
number = int(input_value)
except ValueError:
print(f"input is invalid: {input_value}")
else:
print(f"{number = }")
22
23.
try-except-else# input -> "five"
try:
input_value = input("Enter a number: ")
number = int(input_value) # ValueError
except ValueError:
print(f"input is invalid: {input_value}")
else:
print(f"{number = }")
23
24.
try-except-else# input -> "five"
try:
input_value = input("Enter a number: ")
number = int(input_value) # ValueError
except ValueError:
print(f"input is invalid: {input_value}")
else:
print(f"{number = }")
# input is invalid: five
24
25.
try-except-else# input -> 42
try:
input_value = input("Enter a number: ")
number = int(input_value) # OK
except ValueError:
print(f"input is invalid: {input_value}")
else:
print(f"{number = }")
25
26.
try-except-else# input -> 42
try:
input_value = input("Enter a number: ")
number = int(input_value) # OK
except ValueError:
print(f"input is invalid: {input_value}")
else:
print(f"{number = }")
# number = 42
26
27.
try-except-else# input -> 42
try:
input_value = input("Enter a number: ")
number = int(input_value) # OK
except ValueError:
print(f"input is invalid: {input_value}")
else:
print(f"{number = }")
# number = 42
27
28.
raise# явное создание исключения
raise ValueError("invalid value")
...
ValueError: invalid value
# неявное создание исключения
raise ValueError
...
ValueError:
28
29.
re-raisetry:
raise ValueError("invalid value")
except ValueError as exc:
print(f"exception info: {exc}")
raise
# exception info: invalid value
...
ValueError: invalid value
29
30.
Цепочка исключенийdef connect_to_db() -> None:
raise ConnectionError("fail to connect")
try:
connect_to_db()
except ConnectionError:
raise RuntimeError("transaction failed")
...
ConnectionError: fail to connect
During handling of the above exception, another exception occurred:
...
RuntimeError: transaction failed
30
31.
raise fromdef connect_to_db() -> None:
raise ConnectionError("fail to connect")
try:
connect_to_db()
except ConnectionError as exc:
raise RuntimeError("transaction failed") from exc
...
ConnectionError: fail to connect
The above exception was the direct cause of the following exception:
...
RuntimeError: transaction failed
31
32.
raise from Nonedef connect_to_db() -> None:
raise ConnectionError("fail to connect")
try:
connect_to_db()
except ConnectionError:
raise RuntimeError("transaction failed") from None
...
RuntimeError: transaction failed
32
33.
Механизм распространения ошибокdef raise_() -> None:
print("before raise")
raise Exception("exc from raise_")
print("after raise")
def call_raise() -> None:
print("before calling raise_")
raise_()
print("after calling raise_")
33
34.
Механизм распространения ошибокdef process_exception() -> None:
try:
print("before exception raising")
call_raise()
print("after exception raising")
except Exception as exc:
print(f"process exception:
{exc}")
34
35.
Механизм распространения ошибокprocess_exception()
# before exception raising
# before calling raise_
# before raise
raise Exception(...)
Стек вызовов
raise_
call_raise
process_exception
35
36.
Механизм распространения ошибокprocess_exception()
# before exception raising
# before calling raise_
# before raise
raise Exception(...)
Стек вызовов
call_raise
process_exception
36
37.
Механизм распространения ошибокСтек вызовов
process_exception()
# before exception raising
# before calling raise_
# before raise
raise Exception(...)
# process exception: exc from raise_
process_exception
37
38.
LBYL vs EAFPregistry = {}
key = "key"
# LBYL
if key in registry:
print(registry[key])
# EAFP
try:
print(registry[key])
except KeyError:
pass
сначала
думаем,
потом делаем
сначала
делаем,
потом думаем
38
39.
Экспериментdef get_key_lbyl(
dict_: dict[str, str], key: str
) -> str | None:
if key in dict_:
return dict_[key]
return None
def get_key_eafp(
dict_: dict[str, str], key: str
) -> str | None:
try:
return dict_[key]
except KeyError:
return None
39
40.
Эксперимент: редкие ошибкиimport time
dict_ = {"key": "value"}
time_start = time.time()
for _ in range(10_000_000):
get_key_lbyl(dict_, "key")
print(f"time spent: {time.time() - time_start:.2f}")
# time spent: 0.98
40
41.
Эксперимент: редкие ошибкиimport time
dict_ = {"key": "value"}
time_start = time.time()
for _ in range(10_000_000):
get_key_eafp(dict_, "key")
print(f"time spent: {time.time() - time_start:.2f}")
# time spent: 0.87
41
42.
Эксперимент: частые ошибкиimport time
dict_ = {}
time_start = time.time()
for _ in range(10_000_000):
get_key_lbyl(dict_, "key")
print(f"time spent: {time.time() - time_start:.2f}")
# time spent: 0.87
42
43.
Эксперимент: частые ошибкиimport time
dict_ = {}
time_start = time.time()
for _ in range(10_000_000):
get_key_eafp(dict_, "key")
print(f"time spent: {time.time() - time_start:.2f}")
# time spent: 2.91
43
44.
Контекстные менеджеры44
45.
Захват и освобождение ресурсов# захват ресурса
file = open("file.txt", mode="w")
file.write("Hello, World!")
# освобождение ресурса
file.close()
45
46.
Проблема# захват ресурса
file = open("file.txt", mode="w")
file.write("Hello, World!") # FAIL
# освобождение ресурса не произойдет
file.close()
46
47.
try-finallytry:
file = open("file.txt", mode="w")
file.write("Hello, World!") # OK
print("succesfully write to file")
finally:
file.close()
print("successfully close file")
# succesfully write to file
# successfully close file
47
48.
try-finallytry:
file = open("file.txt", mode="w")
file.write("Hello, World!") # OK
print("succesfully write to file")
finally:
file.close()
print("successfully close file")
# successfully close file
...
UnsupportedOperation: not writable
48
49.
try-except-finallytry:
file = open("file.txt", mode="r")
file.write("Hello, World!")
print("succesfully write to file")
except Exception as exc:
print(exc)
finally:
file.close()
print("successfully close file")
# not writable
# successfully close file
49
50.
try-except-else-finallytry:
# выполняется всегда
pass
except Exception:
# выполняется при ошибке в try-блоке
pass
else:
# выполняется, если в try-блоке нет ошибок
pass
finally:
# выполняется всегда
pass
50
51.
with# файл гарантированно будет закрыт
# что бы ни произошло
with open("test.txt", "w") as file:
file.write("Hello, World!")
51
52.
Множественный withwith (
open("source.txt", "r") as file_read,
open("sink.txt", "w") as file_write,
):
readen_data = file_read.read()
file_write.write(readen_data)
52
53.
Семинар53