Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Python destroy class variables before objects?

I understand that Python doesn't guarantee the order of destruction of objects at the end of the program, or even that it will happen.

So I understand that a class's destructor can't rely on global variables, including other modules.

But I would have thought that objects of the class would have to be destroyed before the class is destroyed. Apparently not:

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()

On Windows 7 x64 Python v2.7.3 I get:

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

I understand the implications of How do I correctly clean up a Python object?. But this case is for class (shared or 'static' for my C++ friends) variables. Surely the instance has a reference to the class variable, which should not be destroyed first as we still have a reference to it?

Is it a problem or a mistake to have the class destroyed before objects of that class? Maybe my question is 'Where are class-shared variables actually stored?"

(Yes, I understand that this can be rectified using a context manager, or even simply:

del a1
del a2

to destroy the object before the class is destroyed.)

like image 913
Peter Avatar asked Mar 14 '13 04:03

Peter


People also ask

Do Python objects have destructors?

A destructor method is called when all references to an object have been destroyed. In Python, the __del__() method is referred to as a destructor method. Destructors aren't as important in Python as they are in C++, because Python contains a garbage collector that takes care of memory management automatically.

What does __ del __ do in Python?

__del__ is a destructor method which is called as soon as all references of the object are deleted i.e when an object is garbage collected. Example: Here is the simple example of destructor. By using del keyword we deleted the all references of object 'obj', therefore destructor invoked automatically.

Which method is automatically invoked when an object is about to be destroyed in Python?

Create Destructor using the __del__() Method This method is automatically called by Python when the instance is about to be destroyed. It is also called a finalizer or (improperly) a destructor.

Do you need to delete variables in Python?

In general, don't worry about deleting variables. Python has garbage collection, so any objects that you can no longer access (usually because you've left their scope) will automatically be freed from memory, you don't have to worry about this at all.


1 Answers

Maybe my question is 'Where are class-shared variables actually stored?"

If that is your question, the answer is "on the class".

To address your larger question: As you noted, __del__ can't rely on global variables — but A is a global variable, so you can't rely on it. Interestingly, I can't find an official statement of this in the docs, but there are various references on the internet to this fact that __del__ can't use global variables. Here is one:

When a Python program terminates the global variables in each module are set to None. The order in which this happens it undefined

It will work if you access the count via self.__class__.count instead of A.count. (This is also why it works when you use self.count.)

like image 113
BrenBarn Avatar answered Oct 16 '22 22:10

BrenBarn