Python 将 class 实例传递给方法并修改 属性 会导致新的、不相关的实例更改默认行为

Python passing class instance to method and modifying property causes new, unrelated instances to change default behavior

在下面的代码中,我定义了一个节点 class,它在实例化时应该有一个空的 "childarr" 属性。然后,我实例化 class 并将其传递给方法 "expnd"。这会向 childarr 数组添加三个新节点。正如预期的那样,第一个 print 语句显示 "node" 实例的 childarr 的长度为 3。但是现在,我从头开始实例化 "Node" class 的一个新实例。由于我在 class 的 init 方法中指定如果没有为该变量传递任何内容,它应该是一个空数组,我期望 nn 有一个空的 childarr 属性。但是,第二个打印语句显示它实际上也有三个 children。

我很困惑为什么 "nn" 会受到实例化之前发生的一些代码的影响,而这些代码与它无关。

有谁知道这种行为的原因以及我在最佳实践方面缺少什么?

class Node():
    def __init__(self, childarr=[]):
        self.childarr = childarr

def expnd(node):
    for i in range(3):
        newnode = Node()
        node.childarr.append(newnode)

node=Node()
expnd(node)
print("Length of child array of expanded node:" + str(len(node.childarr)))

nn = Node()
print("Length of child array of new, unrelated node:" + str(len(nn.childarr)))

问题是您使用相同的空列表实例实例化所有 "empty" childarr,在 __init__ 定义 中创建. 改变这种行为的一种方法:

class Node():
    def __init__(self, childarr=None):
        self.childarr = childarr or []

def expnd(node):
    for i in range(3):
        newnode = Node()
        node.childarr.append(newnode)

node=Node()
expnd(node)
print("Length of child array of expanded node:" + str(len(node.childarr)))

nn = Node()
print("Length of child array of new, unrelated node:" + str(len(nn.childarr)))

结果:

Length of child array of expanded node:3
Length of child array of new, unrelated node:0