【问题标题】: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得到自我。从B类的值到A类函数中的变量,然后在不改变self的情况下改变变量值。 B 类的值
【发布时间】:2019-01-23 04:51:37
【问题描述】:

我想使用 B 类(self.array_B)中的值并将它们分配给 A 类中的变量(array_A),同时在 A 类中执行“step”函数。但是,在我将变量值(array_A)更改为A类中的零,(self.array_B)的值也被更改为零,这很尴尬。 (self.array_B) 在我更改类 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

【问题讨论】:

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


    【解决方案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)
    

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

    【讨论】:

    • 对不起,它不起作用。结果保持不变。
    • 请检查我的答案的深拷贝部分。您需要一个 deepcopy,因为您的列表本身包含列表。
    • 吸取了教训,这是一项昂贵的操作。
    【解决方案2】:

    只需将arrayB 的副本分配给arrayA

    array_A = self.B.array_B.copy()
    

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-04
        • 2021-01-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多