这对我来说真的很令人惊讶(而且调试时间很长(:
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)
我的问题是:
- 这是因为numpy数组(深度复制(的属性吗
- 有没有办法";"修复";对象属性,除非我显式修改它们
对于您的问题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_value和test都指向同一个对象,所以它会被修改。
但是,如果重新指定具有相同标签名称的其他对象,则该标签将从上一个对象中删除,并附加到该新对象。您可以通过使用以下代码检查内存位置来验证这一点:
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情况下,这是一个棘手的问题。