【问题标题】:Cannot clear a list of dictionaries无法清除字典列表
【发布时间】:2016-01-20 13:40:10
【问题描述】:

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

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”的行。当我删除这一行时,一切都按预期工作。在 Windows 7 上使用 Python 2.7.10 和 Python 2.7.11(32 位)在 OS X 上测试了此行为。

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)

【问题讨论】:

  • 你能发布一个最小的、可验证的例子吗?我试图用一个小测试类来验证所描述的行为,但我无法重现你的问题。请发布更多代码。
  • 我无法重现这个......它适用于我,而且在 del 之后它会抛出对象未定义的 NameError 异常。
  • 请发布您的代码。当您使用 del 关键字删除 self.aggregator 时,您应该无法使用它。
  • 我认为你遗漏了一些东西。效果很好。
  • 这一行del self.aggregator 应该删除变量,所以当你询问它的值时你应该得到一个错误。请提供更多代码。

标签: python list dictionary reset


【解决方案1】:

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

self.aggregator = None

自动激活 instance 属性。所以在那之后,它是一个完全不同的变量,它隐藏(隐藏)类属性。除非您执行del self.aggregator,否则您删除实例属性,并取消隐藏类属性,看到原始(共享)值。

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

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 中的引用)和删除引用的list内容 是有区别的self.aggregatordel self.aggregator[:] 或在 Py3.3+ 中,self.aggregator.clear())在self.aggregator 引用的list 的引用可能不止一个的情况下。更多详情请查看Clearing Python lists

【讨论】:

    猜你喜欢
    • 2020-12-15
    • 1970-01-01
    • 2022-01-21
    • 2016-12-18
    • 1970-01-01
    • 2017-06-01
    • 2016-03-30
    • 2020-07-14
    • 1970-01-01
    相关资源
    最近更新 更多