Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python del on classes

Tags:

python

class

del

Lets assume we have a class in python:

class A(object):
    def __del__(self):
        print "Del!"

__del__ is called upon deleting/garbage collection of any A instance.

Is is possible to do the same for a class? I would like to have some method called when the class itself is garbage collected, which I assume is being done at the script exit.

Thanks in advance for any pointers!


Edit: Just as I have expected, everyone is trying to drive me away from using this technique (I would probably make such a comment myself:)), though the question still stands: is it possible?

I want to the the following: I have a class with a static member that needs to be cleaned.

class A(object):
    class Meta(type):
        def __new__(mcs, name, bases, attrs):
            attrs['conn'] = sqlite3.connect( DB_FILE )
            return type.__new__(mcs, name, bases, attrs)

    __metaclass__ = Meta

I would like A.conn.close() to be called, but just before the program closes - i.e. when I know that no more instances of A will be ever created. I know I can do this with atexit, but this just seems very ugly.

like image 959
pajton Avatar asked Apr 09 '11 21:04

pajton


People also ask

How do you remove something from a class Python?

To delete an object in Python, we use the 'del' keyword.

How do I delete an instance of a class in Python?

Remove the instance by deleting it from your population list (containing all the roach instances. If your Roaches are Sprites created in Pygame, then a simple command of . kill would remove the instance. You could use any of the functions in Python to remove the instance from the list, like delete, remove, pop etc.

What is __ delete __ in Python?

__delete__ is used to delete the attribute of an instance i.e removing the value of attribute present in the owner class for an instance. Note: This method only deletes the attribute which is a descriptor. Syntax: def __delete__(self, instance): body of delete . .


1 Answers

The problem is that classes contain circular references back to themselves - so when they are deleted they are not easily collected - thus the __del__ method odf the metaclass is not called.

I could trigger it being called using Pypy's Python implementation, but not using cpython - either 2.6 or 3.2. And even to trigger that, I had to manually invoke the garbage collector - The Python environment at program exit is known to be full of inconsitencies, and the chances of the __del__ method being called while enough internal information on the class would exist to allow a sae shut down would be very slim.

Here is my Pypy session where I did trigger the call to the class' __del__

 ~]$ pypy                                                                                       
Python 2.5.2 (78826, Nov 29 2010, 00:18:05)                                                                       
[PyPy 1.4.0] on linux2                                                                                            
Type "help", "copyright", "credits" or "license" for more information.                                            
And now for something completely different: ``sorry, I'll teach the cactus how                                    
to swim later''                                                                                                   
>>>> import gc
>>>> class Meta(type):         
....    def __del__(cls):                          
....       print ("Arghh!!")                                              
....                                                                      
>>>> class A(object):                                                                     
....   __metaclass__ = Meta                                                                                     
....                                                                                                                                                                                                                
>>>> del A                                                                                                        
>>>> gc.collect()                                                                                                 
Arghh!!                                                                                                           
0                                                                                                                 
>>>>

2022 - as of Python 3.11 a06, the __del__ method in the metaclass works in cPython, if one calls gc.collect() after deleting all references to the class, just like it happens with pypy on this example.

like image 198
jsbueno Avatar answered Oct 15 '22 01:10

jsbueno