考虑下面的小python代码段,在其中将“ 2”添加到3 x 3矩阵的第一列:
import numpy as np
def changeValue(kernel):
kernel[0,0]=kernel[0,0]+ 2
kernel[1,0]=kernel[1,0]+ 2
kernel[2,0]=kernel[2,0]+ 2
return kernel
myKernel = np.array((
[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]), dtype="int")
CVkernel=myKernel
print(CVkernel)
a=changeValue(myKernel)
print(a)
print(CVkernel)
我得到以下输出
[[ 0 -1 0]
[-1 5 -1]
[ 0 -1 0]]
[[ 2 -1 0]
[ 1 5 -1]
[ 2 -1 0]]
[[ 2 -1 0]
[ 1 5 -1]
[ 2 -1 0]]
myKernel副本CVkernel的值。我认为发生了意外的按引用调用(按引用传递?),但是我不确定为什么。
如果我对函数的定义稍有不同
def changeValue2(kernel):
kernel=kernel + 2
return kernel
然后保持CVkernel不变
[[ 0 -1 0]
[-1 5 -1]
[ 0 -1 0]]
[[2 1 2]
[1 7 1]
[2 1 2]]
[[ 0 -1 0]
[-1 5 -1]
[ 0 -1 0]]
这是怎么回事?我尝试使用print(id(kernel))和print(id(CVkernel))打印出变量的地址寄存器,但这并没有说明。
编辑 即使当我使用“安全”函数调用kernel = kernel + 2时,myKernel和CVkernel的ID也相同。
id of myKernel 139994865303344
myKernel
[[ 0 -1 0]
[-1 5 -1]
[ 0 -1 0]]
id of CVKernel 139994865303344
CVKernel
[[ 0 -1 0]
[-1 5 -1]
[ 0 -1 0]]
**call made to changeValue2**
id of myKernel 139994865303344
myKernel
[[ 0 -1 0]
[-1 5 -1]
[ 0 -1 0]]
id of CVKernel 139994865303344
CVKernel
[[ 0 -1 0]
[-1 5 -1]
[ 0 -1 0]]
output a
[[2 1 2]
[1 7 1]
[2 1 2]]
如果每个变量的ID是不同的实例,它们的ID是否应该不同?
答案 0 :(得分:1)
尝试如下操作:
def changeValue2(kernel):
kernel += 2
return kernel
结果显示如下:
[[ 0 -1 0]
[-1 5 -1]
[ 0 -1 0]]
[[2 1 2]
[1 7 1]
[2 1 2]]
[[2 1 2]
[1 7 1]
[2 1 2]]
您很清楚它是a call by reference
,但是,在kernel = kernel + 2
的情况下,左边的kernel
成为另一个实例。简单来说,它与newKernel = kernel + 2
相同。
因此,我将其更改为kernel += 2
,并修改了原始kernel
实例。
答案 1 :(得分:1)
原因
永远不要直接修改对象内核
您传递给函数changeValue2
。
请检查此链接 How arguments passed in python找出尝试修改参数时真正发生的事情
解决方案:
只需使用changeValue
使用返回值:myKernel = changeValue2(myKernel)
只需复制yaho cho的解决方案,再次感谢:)
def changeValue2(kernel):
kernel += 2
return kernel
答案 2 :(得分:-1)
我建议:
CVkernel=myKernel.copy()