python对象属性修改



这对我来说真的很令人惊讶(而且调试时间很长(:

class Test():
def __init__(self):
self.init_value = np.array([1, 2])

def func(self):
test = self.init_value
test[-1] = 0
return test
test = Test()
print(test.init_value)
test.func()
print(test.init_value)

我的问题是:

  1. 这是因为numpy数组(深度复制(的属性吗
  2. 有没有办法";"修复";对象属性,除非我显式修改它们

对于您的问题1(:让我们先看看这里发生了什么,

self.init_value = np.array([1,2])

在内存中创建一个具有所提供值的np.array对象,并为此分配标签self.init_value

现在,在这个步骤中,

test = self.init_value

对于self.init_value所指向的内存位置,将分配另一个标签test。您可以通过如下修改func((来测试这一点:

def func():
test = self.init_value
# Both these values will be same.
print(hex(id(test)))
print(hex(id(self.init_value)))
test[-1] = 0
return test

因此,当您执行test[-1]=0时,您基本上是在访问test指向的对象的最后一个元素,并将其更改为值0,因为self.init_valuetest都指向同一个对象,所以它会被修改。

但是,如果重新指定具有相同标签名称的其他对象,则该标签将从上一个对象中删除,并附加到该新对象。您可以通过使用以下代码检查内存位置来验证这一点:

hex(id(your_label))

问题2:

如果您不希望test修改self.init_value,请按如下方式修改代码以使用deepcopy((:

import copy
test = copy.deepcopy(self.init_value)

这是一个奇怪的引用与值的问题。

因为self是一个引用,所以您的测试变量是对self.init_value…的引用

所以您正在修改属性@matfux的解决方案让您的变量存储self.init值的副本,而不是对它的引用。

老实说,在大多数OOP情况下,这是一个棘手的问题。

最新更新