【问题标题】:List of python objects, each with their own dictionary of arrays. Appending to one appends to all [duplicate]python 对象列表,每个对象都有自己的数组字典。附加到一个附加到所有[重复]
【发布时间】:2013-01-06 01:24:50
【问题描述】:

可能重复:
“Least Astonishment” in Python: The Mutable Default Argument
dictionary shared between objects for no reason?

     class Player():
        zones = {}
        def __init__(self):
            self.zones['hand'] = []
        def InitHand(self):
            for a in range(5):
                self.zones['hand'].append(a)
lst = []
lst.append(Player())
lst.append(Player())
lst[0].InitHand()
print lst[1].zones['hand']

这会打印“[0, 1, 2, 3, 4]”,但我只初始化了第 0 个元素... 如下将它们更改为数组可以解决问题,但对于我来说,我无法弄清楚为什么会发生这种情况。

    class Player2():
        zones = []
        def __init__(self):
            self.zones = []
        def InitHand(self):
            for a in range(5):
                self.zones.append(a)
lst = []
lst.append(Player2())
lst.append(Player2())
lst[0].InitHand()
print lst[1].zones

这会按预期打印“[]”

【问题讨论】:

  • @MartijnPieters 我在这个问题中看不到任何可变的默认参数。
  • @MarkRansom:这就是我说“相关”的原因。原理是一样的,在这种情况下,实例之间共享可变属性而不是函数调用。
  • 在dict版本中,self.zones['hand']self.zoneslookup,找到类变量,然后设置handdict键。在数组版本中,self.zones = []设置一个新的实例变量,然后它覆盖类变量。在这种情况下,查找级联到外部范围,但属性设置在内部范围中创建新变量。

标签: python list memory dictionary


【解决方案1】:

在您的代码中,所有玩家共享同一个zones 字典。在类范围内设置的任何内容都是 class 属性,而不是 instance 属性。

class Player():
    def __init__(self):
        self.zones = {}
        self.zones['hand'] = []
    def InitHand(self):
        for a in range(5):
            self.zones['hand'].append(a)

【讨论】:

  • +1,但我会将其更改为“在类范围内设置的任何内容都是类属性”,因为可以在可能存在实例的任何上下文中设置实例属性(包括类或静态方法)。
猜你喜欢
  • 2020-04-18
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 2022-01-18
  • 1970-01-01
  • 2018-04-30
  • 1970-01-01
相关资源
最近更新 更多