Почему Python уничтожает переменные класса перед объектами?

Я понимаю, что Python не гарантирует порядок уничтожения объектов в конце программы, или даже это произойдет.

Поэтому я понимаю, что деструктор класса не может полагаться на глобальные переменные, включая другие модули.

Но я бы подумал, что объекты класса должны быть уничтожены до того, как класс будет уничтожен. Очевидно нет:

class A(object): count = 0 def __init__(self): A.count += 1 print 'Creating object, there are now', A.count def __del__(self): A.count -= 1 print 'Destroying object, there are now', A.count a1 = A() a2 = A() 

В Windows 7 x64 Python v2.7.3 я получаю:

 Creating object, there are now 1 Creating object, there are now 2 Exception AttributeError: "'NoneType' object has no attribute 'count'" in <bound method A.__del__ of <__main__.A object at 0x0234B8B0>> ignored Exception AttributeError: "'NoneType' object has no attribute 'count'" in <bound method A.__del__ of <__main__.A object at 0x0234BE90>> ignored 

Я понимаю последствия использования Как правильно очистить объект Python? , Но этот случай для переменных класса (shared или «static» для моих друзей C ++). Конечно, экземпляр имеет ссылку на переменную класса, которая не должна быть уничтожена первой, поскольку у нас есть ссылка на нее?

Это проблема или ошибка, чтобы класс был уничтожен перед объектами этого класса? Может быть, мой вопрос: «Где хранятся переменные класса?»

(Да, я понимаю, что это можно исправить с помощью диспетчера контекстов или даже просто:

 del a1 del a2 

уничтожить объект до уничтожения класса.)

Может быть, мой вопрос: «Где хранятся переменные класса?»

Если это ваш вопрос, ответ «на класс».

Чтобы решить свой более большой вопрос: как вы отметили, __del__ не может полагаться на глобальные переменные — но A – глобальная переменная, поэтому вы не можете полагаться на нее. Интересно, что я не могу найти официальное заявление об этом в документах, но есть различные ссылки в Интернете на этот факт, что __del__ не может использовать глобальные переменные. Вот один из них:

Когда программа Python завершает глобальные переменные в каждом модуле, устанавливается значение None. Порядок, в котором это происходит, не определен

Он будет работать, если вы получите доступ к счету через self.__class__.count A.count вместо A.count . (Вот почему он работает, когда вы используете self.count .)