peter-byte
peter-byte

Reputation: 1

derstroy an instance via "del module_x"

I created my own module "MyServer" which have the function ".connect()".

When I have connected to my server

import MyServer
con = MyServer.connect(...)

and I delete my module ("del MyServer") I expect that "con" is also immediately deleted/destroyed.

But it doesn't work. Maybe the reason for that is the garbage collector. But how can I say "delete NOW!" :)

Upvotes: 0

Views: 38

Answers (2)

Duncan
Duncan

Reputation: 95652

If it happens that there are no more references to the object after you execute del then the object may be free immediately or garbage collected later then the object may be destoryed, but this is incidental: del only deletes a reference to an object, it doesn't directly delete any objects. A module will have many other references throughout the system.

If you want to close your connections you should do that explicitly otherwise the connections themselves will be one of many things preventing the module being deleted. In practice you would have to work really hard at deleting a module so it usually isn't worth trying.

Upvotes: 0

Katriel
Katriel

Reputation: 123632

I assume that you're trying to ensure that the connection to the server is closed? This is not the right way to do that. There are several options:

  1. Write a MyServer.disconnect_all() method and use that:

    try: 
        con = MyServer.connect()
    finally:
         MyServer.disconnect_all()
    
  2. Write a con.close() method and use that:

    con = MyServer.connect()
    try:
        ...
    finally:
        con.close()
    
  3. Put the closing logic in the __del__ method of the con object:

    class Connection:
        ...
        def __del__(self):
            # do closing things
    

    and then when you are done with the connection do del con. Note that this is probably not the best option, because del con doesn't actually delete the con object, it just decreases its reference count by one. If anything else is still holding on to it, it won't get deleted.

  4. (The best option.) Write Connection as a context manager, possibly using contextlib.contextmanager to help. Then you can do:

    with con as Connection(...):
        ...
    

    and when the with block is left the connection will automatically be closed (even in the case of an exception) using your closing logic.


If you are interested in why deleting the module object doesn't delete the connection, I encourage you to look into Python's memory management, which is based on reference counting. Whenever you create a reference to an object a counter on that object is increased by one, and whenever a reference is deleted (e.g. with del, by going out of scope, ...) the counter is decreased by one. Whenever this counter reaches zero the object is deleted.

In your case, you make con a connection. This is a reference to the connection object, so it has nonzero reference count. When you delete the module this may or may not reduce the reference count of the connection object, but it won't reduce it to zero -- because con is still a reference and you haven't deleted that!

I think you should try to write the closing logic of your connection explicitly instead of implicitly.

Upvotes: 2

Related Questions