What happens to an instance if you reassign the variable to another instance?

Question

In this exercise, an instance is created and assigned to the variable facade_1. What happens to the instance if the variable is assigned to another object?

Answer

Python (like many other languages) will detect that an object is no longer being used and perform what is called “garbage collection”. During the process, unused objects are released to free up resources. When a variable is assigned to an instance and then assigned to a different instance, the prior assignment will be a candidate for “garbage collection” provided that no other variable is pointing to it. The following code example shows that the instance originally assigned to my_obj is destroyed when the variable is assigned to a new instance.

class TestClass:
    def __init__(self, id):
        self.id = id
        print("Creating object id = " + str(self.id))

    def __del__(self):
        print("Deleting object id = " + str(self.id))

print("Instantiating object 1")
my_obj = TestClass(1)

print("Instantiating object 2")
my_obj2 = TestClass(2)

print("Instantiating object 3")
my_obj = TestClass(3)

# Wait for 10 seconds to show that object 1 is destroyed before the program ends
from time import sleep
sleep(10)
7 Likes

In the above example we see that object 1 is destroyed before our program ends.
Is it always correct to say that: everything is garbage collected after our code is run?

Depends on what you mean by garbage collection.
When your process exits all the memory of the program is reclaimed by the os, but that doesn’t necessarily mean that the program ran garbage collection.
If you care about memory being reclaimed then exiting the process will do that no matter what.
If you care about events happening when a value is forgotten (external resources, flushing buffers, files, etc) then you’d need to think long and hard about whether this would be done correctly by garbage collection.
The values in that example would all get caught by reference counting (not directly triggered by the program exiting, so the exiting is kind of irrelevant), this doesn’t happen when there are cyclical references, not sure whether python as a language promises to clean those up, or if cpython promises that. There’s also a module atexit for making things happen on exit. You also have to keep in mind that if your program exits abnormally (killed or crashed) then your program doesn’t get the chance to clean anything up.

2 Likes

Short answer: yes. A whole lot more, here.

1 Like

I mean if it promises to garbage collect cyclical references before exiting, and if it does, whether that’s in the language spec or just cpython.
Also no clue how exceptions are dealt with during gc for cyclical objects.
Mainly my point is that if relying on events to be triggered by gc … that might not be the easiest thing to get right. No clue though.

2 Likes

What is the function of “self” there? What does ‘self.id’ do?
Confused abut what I am missing. :confused:

3 Likes

The function of “self” is used to represent the instance of the class. For constructors, like the one in the class above, self has to be the first argument. However, it doesn’t have to be “self”. You can choose what you want to represent the instance of the class. I hope my response cleared your doubts. :slight_smile:

2 Likes