简体   繁体   中英

why i don't see destructor being called in python

I'm working on an API written in python . I'm using this article as my help for python destructors.

# api.py
class ApiCfg(object):
    def __init__(self, ...):
        # open a connection to a device
        some_device_open()

    def __del__(self):
        print 'Close a connection to some_device'
        # close a connection to a device
        some_device_close()

# Some code
...
api_cfg = ApiCfg()

# myfile.py
from api import *

# Do some stuff
api.run()

What I'm expecting to see on my screen, once everything is done is a following statement: Close connection to some device . However for some reason I don't. Can someone explain why this is happening?

First of all del does not guarantee that it will be called. It's a 'problem' with certain garbage collectors, namely: circular referencing.

In your particular case I see that on init phase ApiConfig.__init__ you opened connection to some device. It means that you probably incremented a reference counter on your object (and vice versa). Usually when user deals with the devices (file, socket, pipe) he should manage openning/closing it by himself, because del will not be called until reference counter to its object is equal to 0. That is why we usually use with clause to wrap execution of a block that manages device lifecycle properly. For example:

with open("filename") as f:
     for line in f:
        pass

you can define your own with clause by using contextlib.contextmanager decorator or if you need more sophisticated logic, then create a class with enter and exit methods. You can check more in doc and looking at this article .

Also you can do it in more straightforward fashion by just creating and then calling open() and close() methods that are responsible for proper device handling (including proper closing of the device and its gc).

The object is still referenced even when all the operations have been done. If you want to see this line appear, kill the program after the object creation. Python must destruct every object, so the __del__ method will be run.

However, as pointed out in the comments, Python does not guarantee that this method will be called. Since Python works with a garbage collector, you are not supposed (or rather, not expected) to destruct manually the objects. If you want to be sure your __del__ method is called, call the del statement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM