覆盖对象实例并不会释放内存?

4

我有一个Python对象,本质上是其他对象实例的集合。您可以将其他对象附加到它上面(它只是将其存储在列表中)。它是在读取文件时创建的,例如:

def file_reader(file):
    obj = MyCollection()

    for line in file:
        other_obj = line_reader(line)
        obj.append(other_obj)
    return obj

如果我稍后尝试覆盖对象(通过读取不同的文件),原始数据不会被删除,对象只是被扩展。奇怪的是,如果我使用不同的引用,似乎会发生这种情况:
obj1 = file_reader(file)
obj2 = file_reader(file1)

我怀疑我的代码存在循环引用的问题,但我无法理解其逻辑。有人有想法吗?

编辑: MyCollection 的关键部分如下:

class MyCollection(object):

    def __init__(self, objs = []):
        self.objs = objs

   def append(self, obj):
        self.objs.append(obj)

2
你可以展示一下MyCollection()的代码吗?我猜想这个列表是一个类属性,而不是实例属性。 - jonrsharpe
请问您能提供“我的集合”对象的代码吗?这将非常有帮助。 - Marek
编辑了问题以添加集合类。 - jramm
1个回答

8
我猜您现在手头有这样的东西:

我不是很确定,但你可能有类似下面这样的代码:

class MyCollection():
    listOfThings = []
    def __init__(self):

在这种情况下,listOfThings 是一个 类属性,它在 MyCollection 类的所有实例之间共享。相反,您需要一个实例属性,每个实例都有单独的属性:
class MyCollection():
    def __init__(self):
        self.listOfThings = []

编辑: 差一点就行了!

您遇到的问题在于:

def __init__(self, objs = []):

这里的objs被称为“可变默认参数”。默认参数值中的列表在那些没有向__init__传递任何内容的类实例之间共享(例如,定义a = MyCollection([])将创建一个带有单独objs列表的新实例)。
您应该使用:
def __init__(self, objs=None):
    if objs is None:
        objs = []

这是一个涵盖了以下问题的规范问法:"最小惊奇原则"和可变默认参数


非常感谢!我不得不查找“可变默认参数”,然后,哎呀,我的确切示例在指南中:http://docs.python-guide.org/en/latest/writing/gotchas/ - jramm
顺便提一下,列表并未被用作实际类,因为该类还有其他方法。不过你已经找到了问题 :) - jramm
是的,这是一个非常容易找到信息的经典例子,但前提是你已经知道它叫什么! - jonrsharpe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接