【问题标题】:Creating new object keeps data even with default value即使使用默认值,创建新对象也会保留数据
【发布时间】:2020-08-28 13:42:40
【问题描述】:

我很难理解为什么实例 C 保留实例 B 的数据,即使我使用默认的空列表初始化了实例变量 var。为什么忽略默认参数“var = []”?

class A():
    def __init__(self, var=[]):
        self.var = var

B = A()
B.var.append(3)
C = A()
print(C.var)

打印返回

[3]

更奇怪的是:

class A():
    def __init__(self, var=[2]):
        self.var = var

B = A()
B.var.append(3)
C = A()
print(C.var)

打印

[2, 3]

语句self.var = var如何从前面追加到列表中?

【问题讨论】:

  • Python 列表是可变对象。因此,在定义函数时会创建一个新列表,并且每次后续调用都使用相同的列表。这就是为什么你应该避免使用可变对象作为默认参数的原因。请阅读更多 here Second answer here 还告诉您可变对象和不可变对象之间的更多区别。
  • 有意义。我将使用 None 作为默认值,并使用 if 语句来初始化变量

标签: python-3.x default-value instance-variables class-variables


【解决方案1】:

根据given here是什么

Python 变量是一个符号名称,它是一个对象的引用或指针。将对象分配给变量后,您可以按该名称引用该对象。但是数据本身仍然包含在对象中。

B = A()
B.var.append(3)

在这里,A 的引用被传递给 B。因此它们指向相同的数据,但只是用不同的名称调用。所以无论你在 B 上执行什么操作,你也在 A 上执行。

因此,稍后当您将 A 分配给 C 时,C 会引用相同的数据。

如果您不希望这种情况发生,请使用 deepcopy:

class A():
    def __init__(self, var=[]):
        self.var = var
import copy
B = copy.deepcopy(A())
B.var.append(3)
C = A()
print(C.var)

【讨论】:

  • 这个解释对我来说没有多大意义。例如,如果我想创建一个对象列表,我会执行 objects = [A([x]) for x in range(10)] 之类的操作,我认为我不应该进行深度复制。
猜你喜欢
  • 1970-01-01
  • 2015-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-20
  • 1970-01-01
相关资源
最近更新 更多