Python Programming Deep Dive · Practical Python
Object-Oriented Programming in Python
Classes, inheritance, and dunder methods
Object-Oriented Programming in Python
Classes bundle data and behavior together. __init__ initializes new instances, and self refers to the instance inside methods.
class Rectangle:
def __init__(self, width: float, height: float):
self.width = width
self.height = height
def area(self) -> float:
return self.width * self.height
Inheritance and Dunder Methods
Subclasses inherit and can override behavior. Special "dunder" methods like __str__, __eq__, and __len__ let custom objects integrate with built-in functions such as print(), ==, and len().
class Square(Rectangle):
def __init__(self, side: float):
super().__init__(side, side)
Practice questions
What is `self` in a Python method, and why must it be listed explicitly as the first parameter?
Answer
Summary
self refers to the specific instance the method was called on; Python requires it explicitly (rather than implying it, like some other languages) so the mechanism of attribute access stays explicit and consistent.
Longer Answer
self refers to the specific instance the method was called on; Python requires it explicitly (rather than implying it, like some other languages) so the mechanism of attribute access stays explicit and consistent. Unlike languages where 'this'/'self' is implicit, Python makes it a real, visible parameter — which is why you'll get an error if you forget it in a method signature. In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview.
Key Points
selfrefers to the specific instance the method was called on; Python requires it explicitly (rather than implying it, like some other languages) so the mechanism of attribute access stays explicit and consistent- Unlike languages where 'this'/'self' is implicit, Python makes it a real, visible parameter — which is why you'll get an error if you forget it in a method signature
- In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview
- Use the answer to connect the concept back to a realistic production or interview scenario for 'What is
selfin a Python method, and why must it be listed explicitly as the first parameter?'
Comparison / Tradeoffs
| Aspect | Notes |
|---|---|
| Core idea | self refers to the specific instance the method was called on; Python requires it explicitly (rather than implying it, like some other languages) so the mechanism of attribute access stays explicit and consistent. |
| Practical tradeoff | Unlike languages where 'this'/'self' is implicit, Python makes it a real, visible parameter — which is why you'll get an error if you forget it in a method signature. |
Why
Summary
Unlike languages where 'this'/'self' is implicit, Python makes it a real, visible parameter — which is why you'll get an error if you forget it in a method signature.
Longer Answer
Unlike languages where 'this'/'self' is implicit, Python makes it a real, visible parameter — which is why you'll get an error if you forget it in a method signature. In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview.
Key Points
- Unlike languages where 'this'/'self' is implicit, Python makes it a real, visible parameter — which is why you'll get an error if you forget it in a method signature
- In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview
- In an interview, relate 'What is
selfin a Python method, and why must it be listed explicitly as the first parameter?' to implementation decisions, tradeoffs, and operational impact - Use the answer to connect the concept back to a realistic production or interview scenario for 'What is
selfin a Python method, and why must it be listed explicitly as the first parameter?'
Comparison / Tradeoffs
| Aspect | Notes |
|---|---|
| Core idea | Unlike languages where 'this'/'self' is implicit, Python makes it a real, visible parameter — which is why you'll get an error if you forget it in a method signature. |
| Practical tradeoff | In an interview, relate 'What is self in a Python method, and why must it be listed explicitly as the first parameter?' to implementation decisions, tradeoffs, and operational impact. |
What do dunder methods like `__str__`, `__eq__`, and `__len__` actually enable?
Answer
Summary
They let a custom class hook into Python's built-in operators and functions — defining __eq__ makes == work meaningfully for your objects, __len__ makes len(obj) work, and so on.
Longer Answer
They let a custom class hook into Python's built-in operators and functions — defining __eq__ makes == work meaningfully for your objects, __len__ makes len(obj) work, and so on. This is Python's operator-overloading mechanism — implement the right dunder method and built-in syntax 'just works' for your type. In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview.
Key Points
- They let a custom class hook into Python's built-in operators and functions — defining
__eq__makes==work meaningfully for your objects,__len__makeslen(obj)work, and so on - This is Python's operator-overloading mechanism — implement the right dunder method and built-in syntax 'just works' for your type
- In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview
- Use the answer to connect the concept back to a realistic production or interview scenario for 'What do dunder methods like
__str__,__eq__, and__len__actually enable?'
Comparison / Tradeoffs
| Aspect | Notes |
|---|---|
| Core idea | They let a custom class hook into Python's built-in operators and functions — defining __eq__ makes == work meaningfully for your objects, __len__ makes len(obj) work, and so on. |
| Practical tradeoff | This is Python's operator-overloading mechanism — implement the right dunder method and built-in syntax 'just works' for your type. |
Why
Summary
This is Python's operator-overloading mechanism — implement the right dunder method and built-in syntax 'just works' for your type.
Longer Answer
This is Python's operator-overloading mechanism — implement the right dunder method and built-in syntax 'just works' for your type. In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview.
Key Points
- This is Python's operator-overloading mechanism — implement the right dunder method and built-in syntax 'just works' for your type
- In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview
- In an interview, relate 'What do dunder methods like
__str__,__eq__, and__len__actually enable?' to implementation decisions, tradeoffs, and operational impact - Use the answer to connect the concept back to a realistic production or interview scenario for 'What do dunder methods like
__str__,__eq__, and__len__actually enable?'
Comparison / Tradeoffs
| Aspect | Notes |
|---|---|
| Core idea | This is Python's operator-overloading mechanism — implement the right dunder method and built-in syntax 'just works' for your type. |
| Practical tradeoff | In an interview, relate 'What do dunder methods like __str__, __eq__, and __len__ actually enable?' to implementation decisions, tradeoffs, and operational impact. |
How does `super().__init__(...)` help when a subclass overrides `__init__`?
Answer
Summary
It calls the parent class's constructor explicitly, so the subclass can add its own setup on top of the parent's initialization instead of having to duplicate the parent's logic.
Longer Answer
It calls the parent class's constructor explicitly, so the subclass can add its own setup on top of the parent's initialization instead of having to duplicate the parent's logic. This is the standard way to build on inherited behavior rather than re-implementing it from scratch in every subclass. In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview.
Key Points
- It calls the parent class's constructor explicitly, so the subclass can add its own setup on top of the parent's initialization instead of having to duplicate the parent's logic
- This is the standard way to build on inherited behavior rather than re-implementing it from scratch in every subclass
- In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview
- Use the answer to connect the concept back to a realistic production or interview scenario for 'How does
super().__init__(...)help when a subclass overrides__init__?'
Comparison / Tradeoffs
| Aspect | Notes |
|---|---|
| Core idea | It calls the parent class's constructor explicitly, so the subclass can add its own setup on top of the parent's initialization instead of having to duplicate the parent's logic. |
| Practical tradeoff | It calls the parent class's constructor explicitly, so the subclass can add its own setup on top of the parent's initialization instead of having to duplicate the parent's logic. |
Why
Summary
This is the standard way to build on inherited behavior rather than re-implementing it from scratch in every subclass.
Longer Answer
This is the standard way to build on inherited behavior rather than re-implementing it from scratch in every subclass. In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview.
Key Points
- This is the standard way to build on inherited behavior rather than re-implementing it from scratch in every subclass
- In practice, explain where this shows up in production code, what tradeoffs matter, and how you would justify the choice in an interview
- In an interview, relate 'How does
super().__init__(...)help when a subclass overrides__init__?' to implementation decisions, tradeoffs, and operational impact - Use the answer to connect the concept back to a realistic production or interview scenario for 'How does
super().__init__(...)help when a subclass overrides__init__?'
Comparison / Tradeoffs
| Aspect | Notes |
|---|---|
| Core idea | This is the standard way to build on inherited behavior rather than re-implementing it from scratch in every subclass. |
| Practical tradeoff | In an interview, relate 'How does super().__init__(...) help when a subclass overrides __init__?' to implementation decisions, tradeoffs, and operational impact. |
Open in the app to mark lessons complete, take notes and track your progress.