
Python
Advanced class design involves understanding metaclasses, design patterns, descriptor protocol, and sophisticated object creation strategies. Professional Python code uses patterns that scale to large systems while maintaining flexibility and clarity.
The factory pattern creates objects without specifying exact classes. This decouples object creation from usage, making systems more flexible and maintainable.
from abc import ABC, abstractmethod
class Database(ABC):
@abstractmethod
def connect(self):
pass
class PostgresDB(Database):
def connect(self):
return "Connected to PostgreSQL"
class MongoDBConnection(Database):
def connect(self):
return "Connected to MongoDB"
class DatabaseFactory:
_databases = {
"postgres": PostgresDB,
"mongodb": MongoDBConnection
}
@staticmethod
def create_database(db_type):
if db_type not in DatabaseFactory._databases:
raise ValueError(f"Unknown database: {db_type}")
return DatabaseFactory._databases[db_type]()
@staticmethod
def register(db_type, db_class):
DatabaseFactory._databases[db_type] = db_class
# Use factory
postgres = DatabaseFactory.create_database("postgres")
print(postgres.connect())
mongodb = DatabaseFactory.create_database("mongodb")
print(mongodb.connect())
# Register new database type
class SQLiteDB(Database):
def connect(self):
return "Connected to SQLite"
DatabaseFactory.register("sqlite", SQLiteDB)
sqlite = DatabaseFactory.create_database("sqlite")A singleton ensures only one instance of a class exists. Useful for shared resources like database connections or configuration managers.
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
class ConfigManager(Singleton):
def __init__(self):
if not hasattr(self, 'initialized'):
self.settings = {}
self.initialized = True
def set(self, key, value):
self.settings[key] = value
def get(self, key):
return self.settings.get(key)
# Same instance everywhere
config1 = ConfigManager()
config1.set("debug", True)
config2 = ConfigManager()
print(config2.get("debug")) # Output: True
print(config1 is config2) # Output: TrueAbstract base classes define interfaces that subclasses must implement. They enforce contract compliance.
from abc import ABC, abstractmethod
class PaymentProcessor(ABC):
@abstractmethod
def process(self, amount):
"""Process payment"""
pass
@abstractmethod
def refund(self, amount):
"""Refund payment"""
pass
def validate(self, amount):
"""Concrete method available to all"""
return amount > 0
class StripeProcessor(PaymentProcessor):
def process(self, amount):
if not self.validate(amount):
raise ValueError("Invalid amount")
return f"Processed ${amount} via Stripe"
def refund(self, amount):
return f"Refunded ${amount} from Stripe"
class PayPalProcessor(PaymentProcessor):
def process(self, amount):
if not self.validate(amount):
raise ValueError("Invalid amount")
return f"Processed ${amount} via PayPal"
def refund(self, amount):
return f"Refunded ${amount} from PayPal"
# Cannot instantiate abstract class
# processor = PaymentProcessor() # Error!
stripe = StripeProcessor()
print(stripe.process(99.99))Descriptors are objects that define how attributes are accessed. They provide hooks for getting, setting, and deleting attributes.
class Descriptor:
def __get__(self, obj, objtype=None):
if obj is None:
return self
return obj.__dict__.get(self.name, None)
def __set__(self, obj, value):
raise AttributeError("Cannot set this attribute")
def __set_name__(self, owner, name):
self.name = name
class Email(Descriptor):
def __set__(self, obj, value):
if '@' not in value:
raise ValueError("Invalid email")
obj.__dict__[self.name] = value
class User:
email = Email()
def __init__(self, name, email):
self.name = name
self.email = email
user = User("Alice", "alice@example.com")
print(user.email) # Output: alice@example.com
try:
user.email = "invalid"
except ValueError as e:
print(f"Error: {e}")Method Resolution Order (MRO) determines how Python looks up methods in multiple inheritance hierarchies using C3 linearization.
class A:
def method(self):
return "A"
class B(A):
def method(self):
return "B -> " + super().method()
class C(A):
def method(self):
return "C -> " + super().method()
class D(B, C):
pass
d = D()
print(d.method()) # Output: B -> C -> A
print(D.mro()) # Shows method resolution order
# MRO: [D, B, C, A, object]from abc import ABC, abstractmethod
class Plugin(ABC):
@abstractmethod
def execute(self):
pass
class PluginManager:
def __init__(self):
self.plugins = {}
def register(self, name, plugin_class):
self.plugins[name] = plugin_class
def load(self, name):
if name not in self.plugins:
raise ValueError(f"Plugin {name} not found")
return self.plugins[name]()
class EmailPlugin(Plugin):
def execute(self):
return "Sending email..."
class SlackPlugin(Plugin):
def execute(self):
return "Posting to Slack..."
manager = PluginManager()
manager.register("email", EmailPlugin)
manager.register("slack", SlackPlugin)
email = manager.load("email")
print(email.execute())
slack = manager.load("slack")
print(slack.execute())class Registered:
_registry = {}
def __init_subclass__(cls):
cls._registry[cls.__name__] = cls
@classmethod
def get_subclass(cls, name):
return cls._registry.get(name)
@classmethod
def list_subclasses(cls):
return list(cls._registry.keys())
class Animal(Registered):
pass
class Dog(Animal):
pass
class Cat(Animal):
pass
class Bird(Animal):
pass
print(Animal.list_subclasses())
# Output: ['Dog', 'Cat', 'Bird']
dog_class = Animal.get_subclass("Dog")
print(dog_class)| Concept | Remember |
|---|---|
| Factory Pattern | Create objects without specifying exact classes |
| Singleton | Ensure only one instance exists |
| Abstract Classes | Define interfaces subclasses must implement |
| Descriptors | Control attribute access with __get__/__set__ |
| MRO | Method Resolution Order in multiple inheritance |
| Plugin System | Register and load classes dynamically |
| Design Patterns | Reusable solutions to common problems |
| Decoupling | Separate object creation from usage |
Explore more advanced patterns and techniques in the other advanced topics.
Ready to practice? Try challenges or explore more concepts
Resources
Ojasa Mirai
Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.
Learn Deep • Build Real • Verify Skills • Launch Forward