I have created a simple Python class that takes two values as arguments when instantiating it (contents
and resolution
). These arguments are then assigned to class members in the class' __init__
function.
For some reason, one of the class members (contents
) appears to be a reference/pointer while the other is not (resolution
). If I edit contents
on one class, it updates the other even though I've instantiated two completely separate instances of the class. Here's the stripped down example:
TestBaseClasses.py
import cv2
class Frame():
def __init__(self, contents, resolution):
self.contents = contents
self.resolution = [resolution[0], resolution[1]]
def resize(self, fx, fy):
self.contents = cv2.resize(self.contents, (0, 0), fx=fx, fy=fy)
test.py
import cv2
from copy import deepcopy
from TestBaseClasses import Frame
frame = cv2.imread("test_img.png")
h, w, _ = frame.shape
ProcessFrame = Frame(frame, [h, w])
OriginalFrame = Frame(frame, [h, w])
print(type(frame))
print(ProcessFrame is OriginalFrame)
print(ProcessFrame.contents is OriginalFrame.contents)
print(ProcessFrame.resolution is OriginalFrame.resolution)
print(id(ProcessFrame.contents))
print(id(OriginalFrame.contents))
print("########################")
ProcessFrame = Frame(deepcopy(frame), [h, w])
OriginalFrame = Frame(deepcopy(frame), [h, w])
print(type(frame))
print(ProcessFrame is OriginalFrame)
print(ProcessFrame.contents is OriginalFrame.contents)
print(ProcessFrame.resolution is OriginalFrame.resolution)
print(id(ProcessFrame.contents))
print(id(OriginalFrame.contents))
Output from test.py
<class 'numpy.ndarray'>
False
True
False
4405193824
4405193824
########################
<class 'numpy.ndarray'>
False
False
False
4409151200
4491382256
As you can see, I have to make a deepcopy
of the frame
variable in order to prevent it from being linked to the same reference in memory. You can also see that the frame
variables' type is a numpy array (not some sort of reference/pointer).
When I use example one (without deepcopy
) and edit the contents
member in ProcessFrame
, it edits the contents
member in OriginalFrame
. This does not happen when I do the same for resolution
.
What in the world is going on here? I'd like to not have to import the copy module and use deepcopy if I can avoid it.
It should be noted that I am using Python 3.6.
Update
I am beginning to think this is related to the cv2.imread()
function. If I create a new class member and assign contents to it, it has the same value using id()
(i.e. it's pointing to the same place in memory).