6

Suppose there is a program with a couple of objects living in it at runtime.

Is the __del__ method of each object called when the programs ends?

If yes I could for example do something like this:

class Client: __del__( self ): disconnect_from_server() 

4 Answers 4

7

There are many potential difficulties associated with using __del__. Usually, it is not necessary, or the best idea to define it yourself.

Instead, if you want an object that cleans up after itself upon exit or an exception, use a context manager:

per Carl's comment:

class Client: def __exit__(self,ext_type,exc_value,traceback): self.disconnect_from_server() with Client() as c: ... 

original answer:

import contextlib class Client: ... @contextlib.contextmanager def make_client(): c=Client() yield c c.disconnect_from_server() with make_client() as c: ... 
Sign up to request clarification or add additional context in comments.

1 Comment

Also, you can define methods to accomplish the same: docs.python.org/reference/…
6

I second the general idea of using context managers and the with statement instead of relying on __del__ (for much the same reasons one prefers try/finally to finalizer methods in Java, plus one: in Python, the presence of __del__ methods can make cyclic garbage uncollectable).

However, given that the goal is to have "an object that cleans up after itself upon exit or an exception", the implementation by @~unutbu is not correct:

@contextlib.contextmanager def make_client(): c=Client() yield c c.disconnect_from_server() with make_client() as c: ... 

If an exception is raised in the ... part, disconnect_from_server_ does not get called (since the exception propagates through make_client, being uncaught there, and therefore terminates it while it's waiting at the yield).

The fix is simple:

@contextlib.contextmanager def make_client(): c=Client() try: yield c finally: c.disconnect_from_server() 

Essentially, the with statement lets you almost forget about the good old try/finally statement... except when you're writing context managers with contextlib, and then it's really important to remember it!-)

Comments

2

Consider using with-statement to make cleanup explicit. With circular references __del__ is not called:

class Foo: def __del__(self): self.p = None print "deleting foo" a = Foo() b = Foo() a.p = b b.p = a 

prints nothing.

Comments

1

Yes, the Python interpreter tidies up at shutdown, including calling the __del__ method of every object (except objects that are part of a reference cycle).

Although, as others have pointed out, __del__ methods are very fragile and should be used with caution.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.