Master Python Classes: Inheritance, Composition, and Advanced OOP Techniques
This guide explores Python class fundamentals, covering inheritance versus composition, the use of super(), distinctions among instance, class, and static methods, dataclasses, the __dict__ attribute, name mangling, @property, dynamic class creation with type(), and __slots__ for attribute control.
In Python programming, classes are essential for organizing code and enabling reuse, forming the core of object‑oriented programming (OOP) and a key step in mastering Python features.
1. Inheritance and Composition
Inheritance should be used for "is‑a" relationships, while composition is appropriate for "has‑a" relationships.
Dog class inherits from Animal class
Rectangle class inherits from Shape class
Car class inherits from Vehicle class
Composition should be used for "has‑a" relationships, e.g., a Dog has an Owner, a Car has an Engine, a ProjectGroup has members. The Dog object contains an Owner object, the Car object contains an Engine object, and the ProjectGroup object contains multiple Member objects.
2. super() and Its Use
Using super() inside a class allows access to parent class methods.
For example, a Square class can inherit from Rectangle. In Square's __init__ method, super().__init__(length, length) calls the Rectangle initializer with equal length and width, enabling reuse of area and perimeter methods.
3. Instance, Class, and Static Methods
Instance methods belong to objects and can access instance attributes (e.g., intro in Dog ).
Class methods belong to the class, receive cls instead of self , and can only access class attributes (e.g., get_num_dogs ).
Static methods belong to the class but receive neither self nor cls and cannot access any attributes (e.g., description ).
4. Dataclasses
Using a dataclass can automatically generate the __init__ method for a simple class with attributes like (name, age) , reducing boilerplate when many simple properties are needed.
If complex initialization logic is required, a regular class may be more appropriate.
5. __dict__ Attribute
The __dict__ attribute of an object shows its attributes, including dynamically added ones, which is useful for debugging complex objects.
6. Name Mangling
Attributes prefixed with double underscores are name‑mangled (e.g., __name becomes _Dog__name ) to discourage external access, though they can still be accessed if needed.
7. @property and Managed Attributes
The @property decorator creates managed attributes, allowing control over read/write behavior. Defining only a getter makes the attribute read‑only; adding a setter makes it writable.
8. Using type() to Define Classes
Instead of the class keyword, type(name, bases, dict) can dynamically create a class by specifying its name, base classes, and attribute dictionary.
9. __slots__
The __slots__ attribute restricts which attributes can be set on instances, helping enforce a structured design by allowing only predefined attributes (e.g., name and age for a Dog object).
Code Mala Tang
Read source code together, write articles together, and enjoy spicy hot pot together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.