Object lifecycle overview in Python - Time & Space Complexity
Start learning this pattern below
Jump into concepts and practice - no test required
When we create and use objects in Python, some steps happen behind the scenes. Understanding how long these steps take helps us write better programs.
We want to know how the time to create, use, and delete objects changes as we work with more objects.
Analyze the time complexity of the following code snippet.
class MyObject:
def __init__(self, value):
self.value = value
objects = []
n = 10 # Example value for n
for i in range(n):
obj = MyObject(i)
objects.append(obj)
This code creates n objects and stores them in a list.
- Primary operation: Creating an object and adding it to a list.
- How many times: This happens once for each number from 0 to n-1, so n times.
Each new object takes a small, similar amount of time to create and store.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 object creations and list adds |
| 100 | About 100 object creations and list adds |
| 1000 | About 1000 object creations and list adds |
Pattern observation: The work grows evenly as we add more objects; doubling n doubles the work.
Time Complexity: O(n)
This means the time to create and store objects grows directly with the number of objects.
[X] Wrong: "Creating many objects happens instantly and does not add up."
[OK] Correct: Each object takes time to create and store, so many objects add up to more time.
Understanding how object creation time grows helps you explain program speed and resource use clearly, a useful skill in many coding discussions.
"What if we added a nested loop inside the object creation that also runs n times? How would the time complexity change?"
Practice
Solution
Step 1: Understand object lifecycle start
The lifecycle of a Python object begins when it is created in memory.Step 2: Differentiate from other lifecycle stages
Deletion and garbage collection happen later, after creation and use.Final Answer:
Creation of the object in memory -> Option AQuick Check:
Object lifecycle starts with creation [OK]
- Confusing creation with deletion
- Thinking garbage collection happens first
- Assuming variable assignment is the first step
Solution
Step 1: Recall destructor method name
In Python, the destructor method is named __del__ with double underscores before and after.Step 2: Check syntax correctness
The correct syntax is def __del__(self): which matches Python's special method naming.Final Answer:
def __del__(self): -> Option BQuick Check:
Destructor method = __del__ [OK]
- Using wrong method names like destructor or delete
- Missing double underscores
- Confusing with constructor __init__
class MyClass:
def __init__(self):
print('Created')
def __del__(self):
print('Deleted')
obj = MyClass()
print('Object in use')
del obj
print('End')Solution
Step 1: Trace object creation and constructor call
When obj = MyClass() runs, __init__ prints 'Created'.Step 2: Follow print and deletion order
Next, 'Object in use' prints. Then del obj calls __del__, printing 'Deleted'. Finally, 'End' prints.Final Answer:
Created\nObject in use\nDeleted\nEnd -> Option AQuick Check:
Constructor then prints, then destructor after del [OK]
- Assuming destructor runs immediately after creation
- Ignoring order of print statements
- Thinking del obj skips destructor
class Sample:
def __init__(self):
print('Init called')
def __del__(self):
print('Del called')
obj = Sample()
obj = None
print('Done')Solution
Step 1: Understand what happens when obj is set to None
Setting obj = None removes the reference to the Sample object, so it becomes eligible for garbage collection.Step 2: Confirm destructor call behavior
When no references remain, __del__ is called, so 'Del called' will print before 'Done'.Final Answer:
No error; destructor will be called when obj is set to None -> Option CQuick Check:
Destructor runs when object has no references [OK]
- Thinking setting variable to None skips destructor
- Confusing syntax errors with lifecycle behavior
- Assuming constructor is skipped
class Item:
def __init__(self, name):
self.name = name
print(f'Created {name}')
def __del__(self):
print(f'Deleted {self.name}')
def create_items():
items = [Item('a'), Item('b'), Item('c')]
print('Items created')
create_items()
print('Function ended')Solution
Step 1: Analyze object references inside function
Objects are stored in the list 'items' inside create_items(). They exist until the function ends.Step 2: Determine when objects lose references
When create_items() finishes, 'items' list is destroyed, removing references to objects, triggering destructors.Step 3: Confirm output order
So, 'Items created' prints, then function ends, then destructors print, then 'Function ended' prints.Final Answer:
Destructors called after 'Function ended' when function scope ends -> Option DQuick Check:
Objects destroyed after function scope ends [OK]
- Thinking destructors run immediately after creation
- Assuming list keeps objects alive forever
- Confusing print order with destructor timing
