is this Python's pass by reference' behavior?
Question: I thought Python assignment statements were 'pass by value'. For example

    
    
    b=0
    a=b
    b=1
    print(a) #prints 0
    print 
    (b) #prints 1
    

However, I am confused by a different behavior when dealing with other kinds
of data. From this tutorial [on openCV](https://pythonprogramming.net/image-
arithmetics-logic-python-opencv-tutorial/) I modified the code slightly to
show two images. The code below takes this image:
[![](http://i.stack.imgur.com/Obn1w.png)](http://i.stack.imgur.com/Obn1w.png)
and adds it into this image [![enter image description
here](http://i.stack.imgur.com/T4Ldd.png)](http://i.stack.imgur.com/T4Ldd.png)

and repeats the process, adding this image

[![](http://i.stack.imgur.com/LCAh8.png)](http://i.stack.imgur.com/LCAh8.png)

onto the same base image.

    
    
    import cv2
    import numpy as np
    
    # Load two images
    img1 = cv2.imread('3D-Matplotlib.png')
    #img1a = img1
    img1a = cv2.imread('3D-Matplotlib.png')
    img2 = cv2.imread('mainlogo.png')
    img3 = cv2.imread('helloo.png')
    # I want to put logo on top-left corner, So I create a ROI
    rows,cols,channels = img2.shape
    roi = img1[20:rows+20, 20:cols+20]
    
    rows3,cols3,channels3 = img3.shape
    roi3 = img1[50:rows3+50, 50:cols3+50 ]
    
    
    # Now create a mask of logo 
    img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
    # add a threshold
    ret, mask = cv2.threshold(img2gray, 220, 255, cv2.THRESH_BINARY_INV)
    #anything crossing over 220 is thelower limit
    #binary threshold is 0 or 1
    #anything> 220 goes to 255
    #anything below 220 goes to 0-> black
    #and create its inverse mask
    mask_inv = cv2.bitwise_not(mask)
    #do same for img3
    img3gray = cv2.cvtColor(img3,cv2.COLOR_BGR2GRAY)
    ret3, mask3 = cv2.threshold(img3gray, 140, 255, cv2.THRESH_BINARY_INV)
    mask_inv3 = cv2.bitwise_not(mask3)
    
    
    # take the ROI of the plot, and throw the mask over it 
    img1_bg = cv2.bitwise_and(roi,roi,mask = mask_inv)
    
    # Take only region of logo from logo image.
    img2_fg = cv2.bitwise_and(img2,img2,mask = mask)
    
    #do the same with the other mask
    img3_bg = cv2.bitwise_and(roi3,roi3,mask = mask_inv3)
    img3_fg = cv2.bitwise_and(img3,img3,mask = mask3)
    #
    
    dst = cv2.add(img1_bg,img2_fg)
    dst3 = cv2.add(img3_bg,img3_fg)
    
    img1[0:rows, 0:cols ] = dst
    img1a[50:rows3+50, 50:cols3+50 ] = dst3
    
    cv2.imshow('r1',img1)
    cv2.imshow('r3',img1a)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

In the above posted code, I get [![two different
images](http://i.stack.imgur.com/qnTw3.png)](http://i.stack.imgur.com/qnTw3.png)

If I comment out line 7 and uncomment line 8, I would expect the same result
if it was pass by value. But I get something else

[![](http://i.stack.imgur.com/F5kBB.png)](http://i.stack.imgur.com/F5kBB.png).

Both images are the same. Obviously, the manipulations onto img1 are 'carried
over' to img1a because img1a is set to be equal to img1. If the assignment
statement was 'pass by value' (as I would expect from python), then img1 and
img1a should be different. But since they are the same, I conclude that img1
is a ptr that was passed to img1a. Thus, if I try to print img1a, I get the
same data as I would from printing img1.

So maybe images are passed by reference? What other data types in Python
behave this way? Arrays? Dictionaries? Or am I totally wrong and confused.


Answer: Like in Java, everything in Python is passed and assigned by value. All values
(every expression and variable) in Python are references (pointers to
objects), and assigning one variable to another make the second variable point
to the same object as the first.

When you say you are making "manipulations onto img1", what you are doing is
you are calling methods on the object pointed to by `img1` (using the
subscript or slice syntax, e.g. `img1[...] = dst`, is still implicitly calling
methods on the object pointed to by `img1`) that are mutating that object.
Those changes can be seen through any other object pointer that happens to be
pointing to that object. That has nothing to do with passing or assigning.
Calling methods is not assigning or passing. If all you did with `img1` was
simply _assign_ various things to the variable `img1` (i.e. `img1 =
something`), you would indeed see that such statements never have an effect on
what object `img1a` points to. That is what assigning by value means.

