python 函数调用后变量发生意外变化
unexpected change in variable after python function call
考虑以下 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)) 打印出变量的地址寄存器,结果确实如此不发光。
编辑
即使当我使用 'safe' 函数调用时, 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不应该不同吗?
我建议:
CVkernel=myKernel.copy()
尝试如下:
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
实例。
Reason
永远不要直接修改对象内核
你传递给函数 changeValue2
.
请检查这个link
How arguments passed in python 找出当您尝试修改参数时真正发生的事情
Solution:
只需使用changeValue
使用 return 值:myKernel = changeValue2(myKernel)
只是一份yaho cho的解决方案,再次感谢:)
def changeValue2(kernel):
kernel += 2
return kernel
考虑以下 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)) 打印出变量的地址寄存器,结果确实如此不发光。
编辑 即使当我使用 'safe' 函数调用时, 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不应该不同吗?
我建议:
CVkernel=myKernel.copy()
尝试如下:
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
实例。
Reason
永远不要直接修改对象内核
你传递给函数 changeValue2
.
请检查这个link How arguments passed in python 找出当您尝试修改参数时真正发生的事情
Solution:
只需使用
changeValue
使用 return 值:
myKernel = changeValue2(myKernel)
只是一份yaho cho的解决方案,再次感谢:)
def changeValue2(kernel):
kernel += 2
return kernel