Practical Constructor Usage
Real-World Constructor Inheritance Patterns
1. Database Model Inheritance
class BaseModel:
def __init__(self, connection):
self.connection = connection
self.cursor = connection.cursor()
class UserModel(BaseModel):
def __init__(self, connection, table_name='users'):
super().__init__(connection)
self.table_name = table_name
def create_user(self, username, email):
query = f"INSERT INTO {self.table_name} (username, email) VALUES (%s, %s)"
self.cursor.execute(query, (username, email))
Constructor Design Patterns
Initialization Strategies
Pattern |
Description |
Use Case |
Dependency Injection |
Pass dependencies through constructor |
Loose coupling |
Factory Method |
Create objects with flexible initialization |
Complex object creation |
Singleton |
Ensure only one instance is created |
Resource management |
Complex Inheritance Example
class NetworkConfig:
def __init__(self, host='localhost', port=8000):
self.host = host
self.port = port
class SecureNetworkConfig(NetworkConfig):
def __init__(self, host='localhost', port=8000, ssl_cert=None):
super().__init__(host, port)
self.ssl_cert = ssl_cert
self.secure_mode = ssl_cert is not None
def validate_connection(self):
return self.secure_mode
Composition vs Inheritance
graph TD
A[Base Class] --> B[Inheritance]
A --> C[Composition]
B --> D[Child Class]
C --> E[Component Class]
Composition Example
class Logger:
def __init__(self, log_level='INFO'):
self.log_level = log_level
class ServiceManager:
def __init__(self, logger=None):
self.logger = logger or Logger()
def start_service(self):
if self.logger:
self.logger.log(f"Service started at {log_level}")
Error Handling in Constructors
class DatabaseConnection:
def __init__(self, connection_string):
try:
self.connection = self._establish_connection(connection_string)
except ConnectionError as e:
raise ValueError(f"Failed to connect: {e}")
def _establish_connection(self, connection_string):
## Connection logic
pass
Best Practices
- Keep constructors simple and focused
- Use type hints for clarity
- Validate input parameters
- Prefer composition over deep inheritance
At LabEx, we emphasize writing clean, maintainable constructor code that follows solid object-oriented principles.
- Minimize heavy initialization logic
- Lazy load complex resources
- Use
__slots__
for memory efficiency