Message 342967 - Python tracker

Message342967

Author skypickle
Recipients skypickle
Date 2019-05-21.00:31:29
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1558398689.74.0.962126355823.issue36980@roundup.psfhosted.org>
In-reply-to
Content
I often get unexpected results when a called function results in  a change in a variable because the function gets a pass by reference. For example, consider this snippet of code that manipulates the first column of a 3x3 matrix that it gets.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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? 

EDIT Even when I use a 'safe' function call that does not clobber CVkernel, like 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?

Would it possible for the python interpreter/compiler to let me know when a function is going to clobber a variable that is not used in the function or passed to the function or returned by the function
History
Date User Action Args
2019-05-21 00:31:29skypicklesetrecipients: + skypickle
2019-05-21 00:31:29skypicklesetmessageid: <1558398689.74.0.962126355823.issue36980@roundup.psfhosted.org>
2019-05-21 00:31:29skypicklelinkissue36980 messages
2019-05-21 00:31:29skypicklecreate