Reputation: 3549
Consider the following small python snippet where I add '2' to the first column of a 3 x 3 matrix:
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)
I get the following output
[[ 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]]
The value of myKernel clobbers CVkernel. I think there is an unintentional call-by-reference (pass-by-reference?) going on but I am not sure why.
If I define the function slightly differently
def changeValue2(kernel):
kernel=kernel + 2
return kernel
Then CVkernel is left untouched
[[ 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]]
What is going on here? I tried printing out the address register of the variables with print(id(kernel)) and print(id(CVkernel)) and that does not shed any light.
EDIT Even when I use a 'safe' function call, kernel=kernel + 2 , the id of myKernel and CVkernel are the same.
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]]
Shouldn't the id of each variable be different if they are different instances?
Upvotes: 2
Views: 302
Reputation: 11
Reason
You should never directly modify the object kernel
you passed to the function changeValue2
.
please check this link How arguments passed in python to find out what really happened when you try to modify the param
Solution:
just use changeValue
use the return value: myKernel = changeValue2(myKernel)
Just a copy of yaho cho's solusion, Thanks again :)
def changeValue2(kernel):
kernel += 2
return kernel
Upvotes: 1
Reputation: 1779
Try it as below:
def changeValue2(kernel):
kernel += 2
return kernel
It shows the result as below:
[[ 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]]
You know well that It's a call by reference
, but, In case of kernel = kernel + 2
, the left kernel
becomes another instance. Simply, It is same as newKernel = kernel + 2
.
So, I changed it to kernel += 2
, and it modified original kernel
instance.
Upvotes: 1