Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

__del__ at program end

Tags:

python

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()
like image 714
Pawel Furmaniak Avatar asked Aug 24 '10 09:08

Pawel Furmaniak


People also ask

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.

What is Python __ repr __?

Python __repr__() function returns the object representation in string format. This method is called when repr() function is invoked on the object. If possible, the string returned should be a valid Python expression that can be used to reconstruct the object again.

What is __ str __ in Python?

The __str__ method in Python represents the class objects as a string – it can be used for classes. The __str__ method should be defined in a way that is easy to read and outputs all the members of the class. This method is also used as a debugging tool when the members of a class need to be checked.

Can you Del self in Python?

'self' is only a reference to the object. 'del self' is deleting the 'self' reference from the local namespace of the kill function, instead of the actual object.


2 Answers

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:
    ...
like image 175
unutbu Avatar answered Sep 24 '22 01:09

unutbu


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

like image 21
Alex Martelli Avatar answered Sep 21 '22 01:09

Alex Martelli