Ответ 1
Да, хотя это не так много имя переменной, которое вызывает это, а не напрямую.
При выходе из Python все модули также удаляются. Очистка модулей производится путем установки всех глобальных переменных в модуле на None
(поэтому эти ссылки больше не относятся к исходным объектам). Эти глобальные ключи являются ключами словарного объекта, и, поскольку словари упорядочены произвольно, переименование одной переменной может изменить порядок, в котором переменные очищаются.
Когда вы переименовали v
в vb
, вы изменили порядок, в котором сбрасываются переменные, и теперь Person
очищается последним.
Один подход - использовать type(self).num_of_people -= 1
в методе __del__
:
def __del__(self):
type(self).num_of_people -= 1
потому что экземпляр всегда будет ссылаться на класс по-прежнему или проверить, не установлен ли Person
на None
:
def __del__(self):
if Person is not None:
Person.num_of_people -= 1
Две заметки:
-
CPython 3.4 больше не устанавливает глобальные значения в
None
(в большинстве случаев), согласно Безопасное завершение объекта; см. PEP 442. -
CPython 3.3 автоматически применяет рандомизированную соль хеша клавишам
str
, используемым в словареglobals
; это приводит к тому, что поведение, которое вы наблюдаете, еще более случайное, просто повторное выполнение кода несколько раз может или не может вызвать сообщение об ошибке.