2

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

我有一个名为的 python 类Server,它包含该类的实例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对象(只有套接字对象, in Core.CoreSocket),因此没有创建循环引用。

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

当对象被 gc 清理时,为什么Core对象不会被正确破坏?Server我想我只是忘记了一些简单的事情,但我就是不知道它是什么。

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

4

1 回答 1

6

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

class Server(object):
    def __init__(self):
        self.cores = []
于 2013-12-03T02:23:47.970 回答