使用__del__方法清理对象

时间:2013-12-03 02:18:26

标签: python python-2.7 destructor resource-cleanup

我正在开发一个python程序来监视和控制游戏服务器。游戏服务器有许多游戏核心,这些核心处理客户端。

我有一个名为Server的python类,它包含类Core的实例,这些实例用于管理实际的游戏内核。 Core类需要通过TCP-Socket连接到游戏核心,以便将命令发送到特定的游戏核心。要正确关闭这些套接字,Core类有一个__del__方法可以关闭套接字。

一个例子:

class Server(object):
    Cores = [] # list which will be filled with the Core objects
    def __init__(self):
        # detect the game-cores, create the core objects and append them to self.Cores

class Core(object):
    CoreSocket = None # when the socket gets created, the socket-object will be bound to this variable
    def __init__(self, coreID):
        # initiate the socket connection between the running game-core and this python object

    def __del__(self):
        # properly close the socket connection

现在,当我使用Core类本身时,析构函数总是被正确调用。但是当我使用Server类时,Core 中的Server.Cores个对象永远不会被破坏。我已经读过gc有循环引用和类的问题使用析构函数,但Core对象从不引用Server对象(仅Core.CoreSocket中的套接字对象),因此不会创建循环引用。

我通常更喜欢使用with - 语句进行资源清理,但在这种情况下,我需要通过Server类中的许多不同方法发送命令,因此使用with赢了帮助...我也尝试在每个命令上创建并关闭套接字,但是当我需要发送许多命令时,这确实会导致性能下降。使用weakref模块创建的弱引用将无济于事,因为在创建Server对象后,会立即调用析构函数。

Core对象被gc清理掉时,为什么Server个对象不能被正确破坏?我想我只是忘记了一些简单的事情,但我无法弄清楚它是什么。

或者,当对象被清理时,可能有更好的方法来关闭这些套接字?

1 个答案:

答案 0 :(得分:6)

你混淆了类和实例成员。与其他一些语言不同,在类范围定义变量会创建一个类变量,而不是实例变量。当Server实例死亡时,Server类仍然存在,并且仍然保留对核心的引用。改为在self.cores方法中定义__init__

class Server(object):
    def __init__(self):
        self.cores = []