tags:

views:

380

answers:

5

I am reading a code. There is a class in which __del__ method is defined. I figured out that this method is used to destroy an instance of the class. However, I cannot find a place where this method is used. The main reason for that is that I do not know how this method is used, probably not like that: obj1.del(). So, my questions is how to call the __del__ method? Thank you for any help.

+4  A: 

If your class has a __del__ method, it should be called when you do del instance_of_class.

I saw your edit now, so yeah, del obj1 should call the __del__ method of obj1.

Or, to be more precise, it decrements the reference count, and if it reaches 0, __del__ is called.

Edit: See comments below for why this isn't neccessarily true.

nlogax
Thank you. It is what I needed. :)
Verrtex
Why is this answer downvoted?
schmilblick
This isn't entirely true. `del` only decrements the reference count. It doesn't necessarily ensure that `__del__` will get called though.
Jason Baker
It's downvoted because there are many fine points here, the biggest being that GC is optional in Python implementations, so this might not happen at all.
ilya n.
I assumed CPython.
nlogax
@nlogax - it's optional in CPython as well: http://docs.python.org/library/gc.html#gc.disable
Jason Baker
@Jason Baker - I see, didn't know that. Thanks for linkage, I'll edit my answer.
nlogax
Um the gc only comes into play in CPython for reference cycles, see the page you posted Jason: * Since the collector supplements the reference counting already used in Python, you can disable the collector if you are sure your program does not create reference cycles. *
kaizer.se
CPython is reference counting so if you `del name` and `name` is the last reference, the object it pointed to will be destroyed. __del__ is not the function that destroys the object however, it only cleans up!
kaizer.se
+8  A: 

__del__ is a destructor. It is called when an object is garbage collected which happens after all references to the object have been deleted.

In a simple case this could be right after you say del x or, if x is a local variable, after the function ends. In particular, unless there are circular references, CPython (the standard Python implementation) will garbage collect immediately.

However, this is the implementation detail of CPython. The only required property of Python garbage collection is that it happens after all references have been deleted, so this might not necessary happen right after and might not happen at all.

Even more, variables can live for a long time for many reasons, e.g. a propagating exception or module introspection can keep variable reference count greater than 0. Also, variable can be a part of cycle of references — CPython with garbage collection turned on breaks most, but not all, such cycles, and even then only periodically.

Since you have no guarantee it's executed, one should never put the code that you need to be run into __del__() — instead, this code belongs to finally clause of the try block or to a context manager in a with statement. However, there are valid use cases for __del__: e.g. if an object X references Y and also keeps a copy of Y reference in a global cache (cache['X -> Y'] = Y) then it would be polite for X.__del__ to also delete the cache entry.

If you know that the destructor provides (in violation of the above guideline) a required cleanup, you might want to call it directly, since there is nothing special about it as a method: x.__del__(). Obviously, you should you do so only if you know that it doesn't mind to be called twice. Or, as a last resort, you can redefine this method using

type(x).__del__ = my_safe_cleanup_method
ilya n.
+2  A: 

The __del__ method (note spelling!) is called when your object is finally destroyed. Technically speaking (in cPython) that is when there are no more references to your object, ie when it goes out of scope.

If you want to delete your object and thus call the __del__ method use

del obj1

which will delete the object (provided there weren't any other references to it).

I suggest you write a small class like this

class T:
    def __del__(self):
        print "deleted"

And investigate in the python interpreter, eg

>>> a = T()
>>> del a
deleted
>>> a = T()
>>> b = a
>>> del b
>>> del a
deleted
>>> def fn():
...     a = T()
...     print "exiting fn"
...
>>> fn()
exiting fn
deleted
>>>

Note that jython and ironpython have different rules as to exactly when the object is deleted and __del__ is called. It isn't considered good practice to use __del__ though because of this and the fact that the object and its environment may be in an unknown state when it is called. It isn't absolutely guaranteed __del__ will be called either - the interpreter can exit in various ways without deleteting all objects.

Nick Craig-Wood
+1  A: 

The __del__ method, it will be called when the object is garbage collected. Note that it isn't necessarily guaranteed to be called though. The following code by itself won't necessarily do it:

del obj

The reason being that del just decrements the reference count by one. If something else has a reference to the object, __del__ won't get called.

There are a few caveats to using __del__ though. Generally, they usually just aren't very useful. It sounds to me more like you want to use a close method or maybe a with statement.

See the python documentation on __del__ methods.

One other thing to note: __del__ methods can inhibit garbage collection if overused. In particular, a circular reference that has more than one object with a __del__ method won't get garbage collected. This is because the garbage collector doesn't know which one to call first. See the documentation on the gc module for more info.

Jason Baker
+1  A: 

I wrote up the answer for another question, though this is a more accurate question for it.

http://stackoverflow.com/questions/2433130/can-someone-here-explain-constructors-and-destructors-in-python-simple-explanat/2433847#2433847

Here is a slightly opinionated answer.

Don't use del. This is not C++ or a language built for destructors. The del method really should be gone in Python 3.x, though I'm sure someone will find a use case that makes sense. If you need to use _del _, be aware of the basic limitations per http://docs.python.org/reference/datamodel.html:

  • del is called when the garbage collector happens to be collecting the objects, not when you lose the last reference to an object and not when you execution del object.
  • del is responsible for calling any del in a superclass, though it is not clear if this is in method resolution order (MRO) or just calling each superclass.
  • Having a del means that the garbage collector gives up on detecting and cleaning any cyclic links, such as losing the last reference to a linked list. You can get a list of the objects ignored from gc.garbage. You can sometimes use weak references to avoid the cycle altogether. This gets debated now and then: see http://mail.python.org/pipermail/python-ideas/2009-October/006194.html.
  • The del function can cheat, saving a reference to an object, and stopping the garbage collection.
  • Exceptions explicitly raised in del are ignored.
  • del complements new far more than init. This gets confusing. See del-is-not-the-opposite-of-init/">http://www.algorithm.co.il/blogs/index.php/programming/python/python-gotchas-1-del-is-not-the-opposite-of-init/ for an explanation and gotchas.
  • del is not a "well-loved" child in Python. You will notice that sys.exit() documentation does not specify if garbage is collected before exiting, and there are lots of odd issues. Calling the del on globals causes odd ordering issues, e.g., http://bugs.python.org/issue5099. Should del called even if the init fails? See http://mail.python.org/pipermail/python-dev/2000-March/thread.html#2423 for a long thread.

But, on the other hand:

And my pesonal reason for not liking the del function.

  • Everytime someone brings up del it devolves into thirty messages of confusion.
  • It breaks these items in the Zen of Python: o Complex is better than complicated. o Special cases aren't special enough to break the rules. o Errors should never pass silently. o In the face of ambiguity, refuse the temptation to guess. o There should be one-- and preferably only one --obvious way to do it. o If the implementation is hard to explain, it's a bad idea.

So, find a reason not to use del.

Charles Merriam