Home > Mobile >  How to know when an object is deep copied in Python
How to know when an object is deep copied in Python

Time:04-05

I just stumbled across a problem we all hate: when code works but you don't know why.

There are two classes. A frame, and a stack of frames. First, I create an object of class Frame which I call temporary frame, and add an item to it. Then, I push this frame to an object lf_stack of class Stack. Then, I overwrite the variable tf by creating a new class. The question is: why doesn't this change reflect in the stack? Does python push the address of the object to the stack, meaning that when I assign a new object to the variable "tf", it creates a new object with a new address and the one in the stack remains the same?

EDIT: This behavior is beneficial to me, but I need to understand why it happens

Here is the minimal example:

class Stack:
    def __init__(self):
        self.content=[]
    def push(self,item):
        self.content.append(item)
    def pop(self):
        self.content.pop()


class Frame:
    def __init__(self):
        self.variables={}
    def add_variable(self,name,content):
        self.variables[name]=content


def execute_instruction1():
    global lf_stack
    lf_stack.push(tf)
     
     
def execute_instruction2():
    global tf
    tf=Frame()
    lf_stack.push(tf)
    

def main():
    global lf_stack, tf
    lf_stack = Stack()
    tf = Frame() 
    tf.add_variable("Foo",4)
    
    #Here, the temporary frame has a variable Foo with value 4
    print(tf.variables) 
    
    #Here, after adding the temporary frame to a stack, it remains the same
    execute_instruction1()
    print(tf.variables)
    
    #Here, however, I overwrite the variable "tf" and it changes, but
    #I thought it would also change in the stack, but it remains the same
    execute_instruction2()
    print(tf.variables)
    print(lf_stack.content[0].variables)


if __name__ == '__main__':
    main()

CodePudding user response:

Every time your code executes tf = Frame(), python firstly creates a new Frame object and secondly uses tf to refer to it so you can keep track of it.

When your code executes: lf_stack.push(tf), now both tf and the internals of lf_stack are keeping track of the same Frame object. Objects never know the names of the variables keeping track of them (just the number of variables so they can destroy themselves when this count gets to 0).

However, the next time you execute: tf = Frame(), as before you get a new Frame object, but now tf is reused to keep track of the new Frame object. If the internals of lf_stack are keeping track of the previous object, neither are lost.

Also note that there are no deep copies happening here.

  • Related