получить себя. значения из класса B для переменных в функции в классе A, а затем измените значения переменных, не меняя себя. значения в классе B - PullRequest
0 голосов
/ 23 января 2019

Я хочу использовать значения в классе B (self.array_B) и назначить их переменным (array_A) в классе A при выполнении функции «step» в классе A. Однако после того, как я изменю значения переменной (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

Ответы [ 3 ]

0 голосов
/ 23 января 2019

просто назначьте копию arrayB для arrayA:

array_A = self.B.array_B.copy()

Это потому, что хотя arrayB назначено arrayA, это адрес arrayB, а не фактическийего значение присваивается имени arrayA.Поэтому просто используйте метод copy(), чтобы создать копию arrayB, а затем назначьте.

0 голосов
/ 23 января 2019

Решение здесь будет использовать Deepcopy

Почему это происходит? Списки - это изменяемые объекты , что означает, что 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
0 голосов
/ 23 января 2019

При назначении списка здесь:

array_A = self.B.array_B

вы только копируете ссылку на исходный список.Так что A.array_A и B.array_B фактически ссылаются на один и тот же список, и любые изменения в списке будут отражены в обеих ссылках.

Вместо этого вы можете скопировать сам список, используя:

array_A = self.B.array_B.copy()

Теперь A.Array_A и B.Array_B относятся к разным спискам и могут быть изменены независимо.

Если список содержит изменяемые объекты сам по себе, простого copy () недостаточно.Оба списка будут по-прежнему содержать ссылки на одни и те же изменяемые объекты внутри.В этом случае необходима функция deepcopy (), которая также копирует все элементы в списке:

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

Это довольно дорогая операция и должна использоваться только при необходимости.

...