Python, how to ensure that the __del __ () method of an object is called before the module dies?

Earlier today, I asked this question about the __del__() method of an object that uses the imported module. The problem was that __del__() wants to use the os module, but sometimes (not always) the module is already removed. I was told that when the Python program exits, the order in which objects and modules are deleted can be random and undefined. However, for my application, I really need to make sure that the object (an instance of the class that I created) is deleted before the module (in which the object is instantiated) is deleted. Is there any way to do this?

+4
python module destructor
source share
2 answers

As we already told you, you really should not rely on __del__ be called when you exit the interpreter. Two options are enough for this:

First atexit

 import os import atexit class Logger(object): def on_exit(self): print "os: %s." % os logger = Logger() atexit.register(logger.on_exit) 

This ensures that your registrar will be completed upon exit.


* Read a little more about your problem, since you plan that one instance is attached to the module that defines the class of instances, the context manager solution below will not work for this, since there is no way to stay in context for the entire execution of your program. You need to use atexit.register . However, from the point of view of program development, I would prefer to use the context manager to manage my resources than atexit.register , if this allows atexit.register to restructure the code.

The second way (better *) is to make your class a context manager that executes the cleanup code when exiting the context. Then your code will look like this:

 import os class Logger(object): def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): print "os:",str(os) with Logger() as logger: #do something ... 
+10
source share

Attach a link to the function with the keyword parameter:

 import os class Logger(object): def __del__(self, os=os): print "os: %s." %os 

or bind it to a class attribute:

 import os class Logger(object): def __init__(self): self.os = os def __del__(self): print "os: %s." % self.os 

By creating a local (sufficient) link, Python will not look for os as global, but with a local link that is stored with the instance or the function itself, respectively.

Globals are viewed at runtime (therefore, the __del__ function in your other question fails if os already cleared), and the local function is cleared along with the function object or in the case of an instance attribute with an instance.

+3
source share

All Articles