得到自我。 class B 中的值到 class A 中函数中的变量,然后在不更改 self 的情况下更改变量值。 class B 中的值

get self. values from class B to variables in function in class A, and then change the variable values without changing self. values in class B

我想在 class B(self.array_B) 中使用值,并在执行 "step" 时将它们分配给 class A 中的变量 (array_A) class A中的函数。但是,在我将class A中的变量值(array_A)更改为零后,(self.array_B)的值也更改为零这很尴尬。 (self.array_B) 在我更改 class A 中的变量值后应该保持不变。有什么办法可以解决这个问题吗?

import numpy as np

class A:
    def __init__(self):
        self.B = B()

    def step(self):
        print("array_B:", self.B.array_B)
        array_A = np.zeros((2, 2))
        array_A = self.B.array_B

        print("array_A:", array_A)
        for i in range(2):
            for j in range(2):
                array_A[i][j] = 0
        print("------------------")
        print("after changing variable value:array_B:", self.B.array_B)
        print("after changing variable value:array_A:", array_A)
        return "done"

class B:
    def __init__(self):
        self.array_B = [[1, 2], [3, 4]]

def test_main():
    env = A()
    s = env.step()
    print(s)

if __name__ == "__main__":
    test_main()

输出:

array_B: [[1, 2], [3, 4]]
array_A: [[1, 2], [3, 4]]
------------------
after changing variable value:array_B: [[0, 0], [0, 0]]
after changing variable value:array_A: [[0, 0], [0, 0]]
done

在此处分配列表时:

array_A = self.B.array_B

您只是在复制对原始列表的引用。所以 A.array_AB.array_B 实际上引用同一个列表,对列表的任何更改都会反映在两个引用中。

您可以使用以下方式复制列表本身:

array_A = self.B.array_B.copy()

现在A.Array_AB.Array_B指的是不同的列表,可以独立更改。

如果列表本身包含可变对象,那么简单的 copy() 是不够的。两个列表仍将包含对内部相同可变对象的引用。在这种情况下,需要一个 deepcopy() ,它也会复制列表中的所有元素:

import copy
array_A = copy.deepcopy(self.B.array_B)

这是一个相当昂贵的操作,只应在需要时使用。

只需将 arrayB 的副本分配给 arrayA:

array_A = self.B.array_B.copy()

这是因为当 arrayB 被分配给 arrayA 时,它是 arrayB 的地址而不是它的实际值被分配给名称 arrayA。因此,只需使用copy()方法创建arrayB的副本,然后赋值即可。

这里的解决方法就是使用deepcopy

为什么会这样? 列表是 mutable objects,这意味着 array_A 仍然指向内存中与 array_B 相同的对象。

如果您使用的是不可变值列表(如整数),一个简单的

array_A = list(self.B.array_B)

甚至

array_A = self.B.array_B[:]

会成功,因为它会强制 python 实例化一个新列表。

但是在这里,array_B 的项目也是列表,所以如果您这样做:

array_A = list(self.B.array_B)
array_A[0][0] = 3
print(self.B.array_B[0][0] == 3) # >> would print True