0

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

当我连接到我的服务器时

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

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

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

4

2 回答 2

2

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

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

    try: 
        con = MyServer.connect()
    finally:
         MyServer.disconnect_all()
    
  2. 编写一个con.close()方法并使用它:

    con = MyServer.connect()
    try:
        ...
    finally:
        con.close()
    
  3. 将关闭逻辑放在对象的__del__方法中con

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

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

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

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

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


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

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

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

于 2011-05-31T09:13:42.800 回答
0

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

如果你想关闭你的连接,你应该明确地这样做,否则连接本身将成为阻止模块被删除的众多因素之一。实际上,您必须非常努力地删除模块,因此通常不值得尝试。

于 2011-05-31T09:18:01.113 回答