为什么在给定默认参数时不同对象中的属性相互连接?

Why are attributes in different objects connected to each other when a default argument is given?

我正在 python 中实现一个基本节点对象。基本上,我实现了一个节点class,属性为f_pointers,并将其设置为默认值[]。每当我尝试更改 f_pointers 的(比方说)node_a 时,我最终会更改 f_pointers of node_b,它们被编程为完全不相关。

我已经通过将默认值更改为 None 并在 __init__ 中设置 forward_pointers 来解决问题。但是,我仍然想知道将来如何避免这个问题,并可能学到一些关于 Python.

的新知识

为了简单起见,我删除了一些不必要的代码部分。

class Node:
     def __init__(self, f_pointers = []):
          self.f_pointers = f_pointers
     def get_pointers(self):
          return self.f_pointers
     def add_pointers(self, new_pointer):
          self.f_pointers.append(new_pointer)
a = Node()
b = Node()
print(a.get_pointers, b.get_pointers)

>>> [] []

a.add_pointers("a")
print(a.get_pointers, b.get_pointers)

>> ["a"] ["a"]

a.add_pointers("b")
print(a.get_pointers, b.get_pointers)

>> ["a","b"] ["a","b"]

可以看出,a和b是完全不相关的对象(除了它们是同一类型的Node),但会相互影响。为什么会这样?

这是因为您引用的是同一个列表(在 __init__ 默认参数列表定义中实例化的列表,例如 __init__(self, f_pointers=[])。发生的情况是,当您在 __init__ 中说self.f_points = f_pointers 每次实例化 一个新的 Node 对象时基本上 引用同一个列表的方法代码块。

进一步解释原因here

您要做的是为每个 init 实例化一个新列表,例如:

def __init__(self, f_pointers=None):
    self.f_pointers = []

你应该这样做。

class Node:
    def __init__(self, f_pointers=None):
        if f_pointers:
            self.f_pointers = f_pointers
        else:
            self.f_pointers = []
    def get_pointers(self):
        return self.f_pointers
    def add_pointers(self, new_pointer):
        self.f_pointers.append(new_pointer)

a = Node()
b = Node()

print(a.get_pointers(), b.get_pointers())

a.add_pointers("a")
print(a.get_pointers(), b.get_pointers())

你得到这种行为是因为在你的情况下 a.f_pointersb.f_pointers 是同一个列表,它是在你描述你的 class 节点时生成的。
所以 a.f_pointers is b.f_pointers == True 在你的情况下