Python: Encapsulation and Inheritance
Last updated: 2026-09-22
Encapsulation hides the internal details of an object, exposing only safe operational interfaces. Inheritance lets one class automatically have the functionality of another, avoiding repetition. These two concepts are the backbone of object-oriented programming.
1. Encapsulation and Private Attributes
Encapsulation means that an object's internal data should not be directly accessed from outside — it should be manipulated through methods.
(1) Single Underscore _ — Convention for "Protected" Attributes
▶ Example: Single and Double Underscore
▶ Try it YourselfOutput:
# Function defined successfully
A single underscore is just a convention, not enforced — Python won't stop you from accessing it. It's like writing in the documentation "this is internal, don't touch."
(2) Double Underscore __ — Name Mangling
▶ Example: Bank Account Class
▶ Try it YourselfOutput:
# Function defined successfully
Double underscores trigger name mangling — __balance is internally transformed to _BankAccount__balance. This isn't true "privacy," just making accidental overriding less likely.
Tip: Python has no true private. It relies on the "we are all consenting adults" understanding — single underscore means "internal use," double underscore prevents name collisions. Other languages (like Java) have a true
privatekeyword; Python doesn't and isn't planning to add one.
▶ Example: Temperature Class (Difficulty: Star-Star)
▶ Try it YourselfOutput:
Temperature cannot be below absolute zero!
2. @property: Elegant Access Control
Writing set_celsius() / get_celsius() is verbose. @property lets you control access while keeping the syntax of attribute access:
▶ Example: Using @property
▶ Try it YourselfOutput:
# Function defined successfully
Tip: Advantages of
@property: 1) No parentheses needed for access:t.celsiusinstead oft.get_celsius(). 2) Automatic validation on assignment:t.celsius = valueinstead oft.set_celsius(value). 3) Can convert a regular attribute to a computed one without breaking existing code.
3. Inheritance
Inheritance lets a child class have all the attributes and methods of its parent class:
▶ Example: Animal Inheritance
▶ Try it YourselfOutput:
# Function defined successfully
(1) super(): Calling Parent Methods
▶ Example: super() to Call the Parent
▶ Try it YourselfOutput:
# Function defined successfully
4. Mixin Pattern
A Mixin is a special class — not used independently, but "mixed in" to add functionality to other classes:
▶ Example: Mixin Pattern
▶ Try it YourselfOutput:
# Function defined successfully
Tip: Mixin naming convention: Class names ending in
Mixinindicate they are for mixing in, not for standalone use. A class can mix in multiple Mixins plus one main base class — much more flexible than deep single inheritance.
5. Common Use Cases
- Data validation: Use
@property.setterto ensure data validity on assignment. - Read-only properties: Use
@propertywithout a setter for read-only attributes. - Code reuse: Put common functionality in the base class; subclasses only write the differences.
- Functional composition: Use Mixins to flexibly add features to different classes.
❓ FAQ
@property and a regular method?@property makes a method look like an attribute — no parentheses for access, assignment triggers the setter. It's essentially an "attribute interceptor" — you write code as if manipulating an attribute, but a method actually executes.class C(A, B). However, multiple inheritance has the "diamond problem" (which parent method to use when both have the same name). Python uses MRO (Method Resolution Order), searching left to right. Mixins are a design pattern that leverages multiple inheritance, with Mixin classes being small and functionally independent, avoiding diamond issues.📖 Summary
- Encapsulation:
_means "don't touch";__triggers name mangling;@propertyprovides elegant access control - Inheritance: child classes automatically have parent attributes and methods;
super()calls parent methods - Method overriding: child class redefines a method with the same name as the parent
- Mixin: use multiple inheritance to flexibly add functionality; preferable to deep inheritance
- Python has no true private attributes — relies on convention and name mangling
📝 Exercises
-
Beginner (Difficulty: Star): Define a
Productclass with@propertyfor thepriceattribute — must be positive when setting; returns the original value when getting. -
Intermediate (Difficulty: Star-Star): Define a three-level inheritance:
Animal->Mammal->Dog/Cat.Animalhasnameandage;Mammaladdsfur_color;DogandCateach implement their ownspeak()method. -
Advanced (Difficulty: Star-Star-Star): Create a logging system with
LoggableMixin(provideslog_info(),log_error()methods) and a base classApplication(has anameattribute). HaveWebAppandCLIAppboth inherit fromApplicationand mix inLoggableMixinto implement logging functionality.