【问题标题】:Why are attributes in different objects connected to each other when a default argument is given? [duplicate]当给出默认参数时,为什么不同对象中的属性会相互连接? [复制]
【发布时间】:2019-08-23 15:15:27
【问题描述】:

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

我已经通过将默认值更改为 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)但会相互影响。为什么会这样?

【问题讨论】:

  • 您的问题被称为“可变默认参数”。在我作为副本链接到的问题中阅读它。

标签: python class object arguments default


【解决方案1】:

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

原因进一步解释here

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

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

【讨论】:

    【解决方案2】:

    你应该这样做。

    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 是同一个列表,它是在您描述类 Node 时生成的。
    所以a.f_pointers is b.f_pointers == True在你的情况下

    【讨论】:

      猜你喜欢
      • 2020-04-16
      • 1970-01-01
      • 2019-07-15
      • 2016-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-26
      • 1970-01-01
      相关资源
      最近更新 更多