我是否使用了错误的列表?这个简单python/pyglet代码中的内存泄漏

我是否使用了错误的列表?这个简单python/pyglet代码中的内存泄漏,python,list,memory-leaks,pyglet,Python,List,Memory Leaks,Pyglet,我正在用pyglet编写一个简单的“避免敌人倒下”类型的游戏。对象在屏幕上方生成,向下移动,并在通过可见屏幕下方时被销毁。然而,我做了一些非常错误的事情,程序运行的时间越长,对象的数量就越高。速度变慢了,我发现了objgraph的问题。当我删除这个类时,问题就消失了 堕落的敌人阶级: class Enemy(pyglet.sprite.Sprite): def __init__(self, **kwargs): super(Enemy, self).__init__(im

我正在用pyglet编写一个简单的“避免敌人倒下”类型的游戏。对象在屏幕上方生成,向下移动,并在通过可见屏幕下方时被销毁。然而,我做了一些非常错误的事情,程序运行的时间越长,对象的数量就越高。速度变慢了,我发现了objgraph的问题。当我删除这个类时,问题就消失了

堕落的敌人阶级:

class Enemy(pyglet.sprite.Sprite):
    def __init__(self, **kwargs):
        super(Enemy, self).__init__(img=images.enemy_anim["front"], **kwargs)
        self.out_of_bounds = False

    def update(self, dt):
        self._move(dt)
        self._check_boundaries(dt)
        self._check_kill_condition()

    def _move(self, dt):
        self.y -= ENEMY_SPEED * dt

    def _check_boundaries(self, dt):
        if self.y + self.height < 0:
            self.out_of_bounds = True

    def _check_kill_condition(self):
        if self.out_of_bounds:
            enemy_list.remove(self)
            self.delete
我有我的敌人动画存储在一个单独的模块图像在字典图像。敌人动画

我用列表中的引用创建了一个敌人

当敌人死后,我告诉他把自己从名单上除名。我在运行时检查了列表的长度,它始终是适当的长度。所以这个名单并没有失控。对象从列表中删除后应该没有引用,对吗

我做错了什么

编辑:


问题是我使用了self.delete而不是self.delete。愚蠢的错误…

与其在自己的方法中删除对象,不如换一种方法,在额外的时间间隔内删除精灵,如下所示:

def delete_enemy(*args, **kwargs):
    items_to_delete = []
    for enemy in enemy_list:
        if enemy.out_of_bounds:
            items_to_delete.append(enemy)
    for item in items_to_delete:
        enemy_list.remove(item)

pyglet.clock.schedule_interval(delete_enemy)
当然,移除线路本身。\检查\杀死\敌方更新中的情况


编辑:我不知道pyglet,但如果这种方法也不起作用,那么pyglet中的某些东西会保留对您的精灵的引用。精灵可以在画布或类似对象中引用。pyglet中应该有一个API调用来完全删除精灵,即从画布中删除精灵。然后,应该在我的敌人列表.removietem调用之后立即使用此调用。

不是在其自己的方法中删除对象,而是采用另一种方法,在额外的时间间隔内删除精灵,如下所示:

def delete_enemy(*args, **kwargs):
    items_to_delete = []
    for enemy in enemy_list:
        if enemy.out_of_bounds:
            items_to_delete.append(enemy)
    for item in items_to_delete:
        enemy_list.remove(item)

pyglet.clock.schedule_interval(delete_enemy)
当然,移除线路本身。\检查\杀死\敌方更新中的情况


编辑:我不知道pyglet,但如果这种方法也不起作用,那么pyglet中的某些东西会保留对您的精灵的引用。精灵可以在画布或类似对象中引用。pyglet中应该有一个API调用来完全删除精灵,即从画布中删除精灵。这个调用应该在我的敌人_list.removietem调用之后立即使用。

正如上面的评论所指出的,问题是我只是忘记了pyglet sprite delete方法上的一对括号。一个简单而明显的错误导致了一个巨大的问题…

正如上面的评论所指出的,问题是我忘记了pyglet sprite delete方法中的一对括号。一个简单而明显的错误导致了一个巨大的问题…

在“检查”和“杀死”条件中,最后一行是否正确?它不应该像self.delete一样吗?哇,这就解决了它。多么愚蠢的错误……在检查、杀死的情况下,最后一行是正确的吗?它不应该像self.delete一样吗?哇,这就解决了它。多么愚蠢的错误啊……pyglet中有一个API调用完全删除一个精灵,你是对的。是sprite.delete,我有sprite.delete。谢谢你的帮助!你说得对,pyglet中有一个API调用来完全删除一个精灵。是sprite.delete,我有sprite.delete。谢谢你的帮助!嗨,乔希,我建议你把马维马维的答案标记为正确。他是一个值得称赞的人,因为他确实详细地回答了这个问题。我不知道,这取决于你,这看起来很公平。很好的一天!嗨,乔希,我建议你把马维马维的答案标记为正确。他是一个值得称赞的人,因为他确实详细地回答了这个问题。我不知道,这取决于你,这看起来很公平。很好的一天!