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

时间:2019-01-23 04:51:38

标签: python-3.x copy deep-copy

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

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

3 个答案:

答案 0 :(得分:1)

在此处分配列表时:

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)

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

答案 1 :(得分:0)

只需将arrayB的副本分配给arrayA

array_A = self.B.array_B.copy()

这是因为在将arrayB分配给arrayA的同时,它是arrayB的地址,而不是其实际值被分配了名称arrayA。因此,只需使用方法copy()创建arrayB的副本,然后进行分配。

答案 2 :(得分:0)

解决方案在这里是使用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