通过“del module_x”销毁实例

发布于 2024-11-10 14:46:07 字数 245 浏览 3 评论 0原文

我创建了自己的模块“MyServer”,其功能为“.connect()”。

当我连接到我的服务器

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

并删除我的模块(“del MyServer”)时,我希望“con”也被立即删除/销毁。

但这不起作用。也许原因是垃圾收集器。但我怎么能说“现在删除!” :)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

活泼老夫 2024-11-17 14:46:07

我假设您正在尝试确保与服务器的连接已关闭?这不是正确的方法。有几个选项:

  1. 编写一个 MyServer.disconnect_all() 方法并使用它:

    <前><代码>尝试:
    con = MyServer.connect()
    最后:
    MyServer.disconnect_all()

  2. 编写一个 con.close() 方法并使用它:< /p>

    con = MyServer.connect()
    尝试:
        ...
    最后:
        con.close()
    
  3. 将关闭逻辑放入 __del__ 方法中con 对象:

    类连接:
        ...
        def __del__(自我):
            # 做关闭的事情
    

    然后当您完成连接后,执行del con。请注意,这可能不是最好的选择,因为 del con 实际上并没有删除 con 对象,它只是将其引用计数减一。如果还有其他东西保留着它,它就不会被删除。

  4. (最好的选择。)将 Connection 编写为上下文管理器,可能使用 contextlib.contextmanager 来提供帮助。然后你可以这样做:

    以 con 作为连接(...):
        ...
    

    with 块离开时,连接将使用您的关闭逻辑自动关闭(即使在异常情况下)。


如果您对为什么删除模块对象不会删除连接感兴趣,我鼓励您研究一下 Python 的内存管理,它基于引用计数。每当您创建对对象的引用时,该对象上的计数器就会加一,而每当删除引用时(例如,使用del,通过超出范围,...),计数器就会减少一个。每当该计数器达到零时,对象就会被删除。

在你的情况下,你建立了一个连接。这是对连接对象的引用,因此它具有非零引用计数。当您删除模块时,这可能会或可能不会减少连接对象的引用计数,但不会将其减少到零 - 因为 con 仍然是一个引用,并且您还没有删除它!

我认为你应该尝试显式而不是隐式地编写连接的关闭逻辑。

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.

南城追梦 2024-11-17 14:46:07

如果执行del后碰巧没有更多对该对象的引用,那么该对象可能会立即释放,或者稍后被垃圾收集,然后该对象可能会被销毁,但这是偶然的:del 仅删除对对象的引用,它不会直接删除任何对象。一个模块在整个系统中会有许多其他引用。

如果您想关闭连接,则应该明确执行此操作,否则连接本身将成为阻止删除模块的众多因素之一。在实践中,您必须非常努力地删除模块,因此通常不值得尝试。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文