无法清除字典列表

Cannot clear a list of dictionaries

一个对象有一个字典列表:

self.aggregator = []
self.aggregator.append({'type': 'Log', 'entry': logline1})
self.aggregator.append({'type': 'Log', 'entry': logline2})
print self.aggregator

到目前为止一切正常:

[{'type': 'Log', 'entry': 'Content of logline 1'}, {'type': 'Log', 'entry': 'Content of logline 2'}]

然后我尝试使用不同的方法重置此列表的内容:

self.aggregator = []
del self.aggregator

现在当我打印列表时它是空的:

[]

但是当我检查列表的长度时,它仍然是原来的大小:

>> print len(self.aggregator)
2

为什么这是可能的,我错过了什么吗?

===更新

下面是完整的演示代码。我想出了导致错误的原因。这是带有 "del self.aggregator" 的行。当我删除此行时,一切都按预期进行。使用 Python 2.7.10 和 Python 2.7.11(32 位)在 OS X 上测试此行为 Windows 7.

class Checker(object):

    aggregator = []
    aggregator_max = 10

    def __init__(self):
        pass

    def finalizeAggregator(self):
        string = "\n".join([attribute['string'] for attribute in self.aggregator])

        # Check for a match on all the aggregator content
        match_result = self.checkString(string,"")

        if match_result:
            # If match has been found, check the aggregator contents one by one
            for element in self.aggregator:
                self.checkString(element["string"],
                                 element["module"],
                                 use_aggregator=False)

        # Clear aggregator
        print self.aggregator
        self.aggregator = None
        self.aggregator = []
        del self.aggregator
        print self.aggregator
        print len(self.aggregator)

    def checkString(self, string, module, use_aggregator=False):

            # If aggregator should be used
            if use_aggregator:
                print "USING aggregator"

                # As long as the aggregator is not full
                if len(self.aggregator) <= self.aggregator_max:

                    #if string not in self.aggregator:
                    # Add element to aggregator
                    self.aggregator.append({"string": string,
                                            "module": module})

                # Process aggregator if full
                if len(self.aggregator) >= self.aggregator_max:
                    self.finalizeAggregator()

                # Otherwise return
                else:
                    return False

            else:
                print "NOT using aggregator"

            if "evil" in string:
                print "WARNING!!!"

if __name__ == '__main__':
    checker = Checker()
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is evil', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)
    checker.checkString('This is benign', 'test', use_aggregator=True)

您将 aggregator 定义为 class 属性;在您直接分配给 self.attribute 之前,它是一个 shared class 属性。但是当你这样做时:

self.aggregator = None

那 auto-vivifies 一个 实例 属性。所以在那之后,它是一个完全不同的变量,它隐藏(隐藏)了 class 属性。除了当您执行 del self.aggregator 时,您删除实例属性,并取消隐藏 class 属性,看到原始(共享)值。

如果目标是拥有实例属性,请使用实例属性。变化:

class Checker(object):

    aggregator = []
    aggregator_max = 10

    def __init__(self):
        pass

至:

class Checker(object):
    aggregator_max = 10

    def __init__(self):
        self.aggregator = []

并且它只是一个实例变量(如果您打算稍后使用它,请不要 del 实际属性,这是荒谬的;分配空的 list 没问题)。

请注意,分配空 list(替换 self.aggregator 中保留的 reference)和删除 之间存在差异contentslist of the list referenced by self.aggregator (del self.aggregator[:] or in Py3.3+, self.aggregator.clear()) 在可能有多个引用的情况下到 self.aggregator 引用的 list。查看 Clearing Python lists 了解更多详情。