在 Python 中,特别是涉及到对象和数据结构(如列表、字典、numpy 数组等)的赋值操作时,理解浅拷贝和深拷贝的区别是很重要的。
self.sd_mx = self.adj_mx.copy()
使用 self.adj_mx.copy()
而不是直接使用 self.adj_mx
是为了创建一个独立的副本(浅拷贝)以避免对原始数据进行不必要的修改。
解释
-
直接赋值(引用传递):
- 如果你直接使用
self.adj_mx
来赋值self.sd_mx
:
这种情况下,self.sd_mx = self.adj_mx
self.sd_mx
和self.adj_mx
都指向同一个对象。对self.sd_mx
进行的任何修改都会反映在self.adj_mx
上,反之亦然。这是因为它们共享同一个引用。
- 如果你直接使用
-
浅拷贝:
- 使用
self.adj_mx.copy()
会创建一个新的对象,self.sd_mx
是这个新对象的引用:self.sd_mx = self.adj_mx.copy()
浅拷贝创建一个新的对象,但新对象中包含的元素仍然是原来对象中元素的引用。如果self.adj_mx
是一个包含简单数据类型(如整数、浮点数)的 numpy 数组,那么copy()
会创建一个独立的副本,并且修改self.sd_mx
的数据不会影响self.adj_mx
。
- 使用
示例说明
假设 self.adj_mx
是一个 numpy 数组:
import numpy as np
class Example:
def __init__(self, adj_mx):
self.adj_mx = adj_mx
self.sd_mx = self.adj_mx.copy()
def modify_sd_mx(self):
self.sd_mx[0, 0] = 99
# 创建一个示例 numpy 数组
adj_mx = np.array([[1, 2], [3, 4]])
# 创建 Example 对象
example = Example(adj_mx)
# 修改 sd_mx
example.modify_sd_mx()
print("self.adj_mx:")
print(example.adj_mx)
print("self.sd_mx:")
print(example.sd_mx)
"""
# Output
self.adj_mx:
[[1 2]
[3 4]]
self.sd_mx:
[[99 2]
[ 3 4]]
"""
从输出可以看出,self.sd_mx
的修改没有影响 self.adj_mx
,因为 self.sd_mx
是 self.adj_mx
的浅拷贝。
最后
使用 self.adj_mx.copy()
是为了确保 self.sd_mx
是一个独立的副本,这样在修改 self.sd_mx
时不会影响到 self.adj_mx
。这通常是为了避免不必要的副作用和数据污染,确保数据的独立性和完整性。在处理复杂数据结构时,理解和正确使用浅拷贝和深拷贝是非常重要的。