Почему у нас два разных поведения на этих np.array?
def pass_by_ref(A: np.array):
A = np.ones((2,2))
return A
def pass_by_ref_sideEffect(A: np.array):
A[0][0] = 2
return A
A = np.zeros((2,2))
B = pass_by_ref(A)
print("A =\n", A)
print("B =\n", B)
C = pass_by_ref_sideEffect(A)
print("A =\n", A)
print("C =\n", C)
выход:
A =
[[0. 0.]
[0. 0.]]
B =
[[1. 1.]
[1. 1.]]
A =
[[2. 0.]
[0. 0.]]
C =
[[2. 0.]
[0. 0.]]
Почему у нас есть побочный эффект на A после pass_by_ref_sideEffect, а не с pass_by_ref?
так что мы не передаем A по ссылке? все же у нас есть два поведения
Это не имеет ничего общего с тем, как вы передаете переменную, и все, что связано с тем, как работает присваивание. В pass_by_ref()
эта строка A = np.ones((2,2))
создает новый массив и присваивает ему локальное имя A
. Исходный объект массива все еще существует, но A
больше не ссылается на него. В другом случае вы манипулируете исходным массивом, присваивая его элементу с помощью A[0][0] = 2
.
Если вы хотите иметь побочный эффект в первом случае, то назначьте срезу А вот так:
def pass_by_ref(A: np.array):
A[:,:] = np.ones((2,2))
return A
A = np.zeros((2,2))
B = pass_by_ref(A)
print(A)
[[1., 1.],
[1., 1.]]
print(B)
[[1., 1.],
[1., 1.]]
Вот пример, демонстрирующий это без передачи переменных в функции:
In [1]: import numpy as np
In [2]: A = np.zeros((2,2))
In [3]: B = A
In [4]: B
Out[4]:
array([[0., 0.],
[0., 0.]])
In [5]: A[:,:] = np.ones((2,2))
In [6]: B
Out[6]:
array([[1., 1.],
[1., 1.]])
Когда Python вызывает функцию, он передает ссылку на объект. Когда вы используете A[0][0] = 2
для назначения, оно будет смещено в соответствии с адресом объекта, на который указывает переменная A
, найдите адрес для записи. Но если вы используете A = np.ones((2, 2))
, будет создан новый массив, и переменная make A
будет указывать на него.
Объекты передаются по ссылке, переменные — нет.