Позвольте мне показать вам мою любимую причуду Python. Что бы вы ожидали, что этот код Python будет делать?
e = 2.718 try: 1/0 except ZeroDivisionError as e: pass print(e)
Если вы приедете на Python с другого языка программирования, вы можете ожидать, что кроме
Пункт вводит вложенную область, так что назначение E
В пункте не влияет ранее существовавшее E
переменная во внешней области. Тем не менее, в структурах управления Python, как правило, не вводят вложенную область (понимание является исключением), поэтому с большим опытом Python вы, вероятно, ожидаете, что это печатает ZerodivisionError
пример.
На самом деле, в стандартной реализации CPYTHON он ничего не печатает; Вместо этого последняя строка поднимает NameError
Анкет Это ошибка? На самом деле это было Довольно намеренно Анкет Если вы посмотрите на байт -код, сгенерированный по пункту, вы видите:
LOAD_CONST 0 (None) STORE_NAME 1 (e) DELETE_NAME 1
Когда поток управления выходит из кроме
Блок, Python удаляет имя из области. Почему? Потому что исключение содержит ссылку на текущую кадр стека, которая содержит Все в рамках. Поскольку Python управляет первичной памятью посредством количества ссылок, это означает, что ничто в текущем сфере не будет освобождено до следующего раунда сбора мусора, если вообще не будет. Текущее поведение – это компромисс между использованием памяти, простотой реализации и чистотой языка. Это немного бородавка, но я думаю, что это воплощает одну из вещей, которые мне нравятся в Python: не позволяя чистоте мешать практичности.
Но это только объясняет Delete_name
инструкция Почему Cpython устанавливается E
к Нет
Если он удалит его сразу после этого? Что ж, представьте, что у вас была та же мысль, что и команда CPYTHON, и решил очистить ссылку на исключение в конце вашего кроме
блокировать:
try: 1/0 except ZeroDivisionError as e: ... del e
В конце твоего кроме
Блок, cpython попытается удалить имя E
– Что вы уже удалили! Чтобы обойти это, CPYTHON назначает E
Перед удалением E
гарантировать, что E
существуют.
Оригинал: “https://dev.to/alexbecker/pythons-except-quirk-5ble”