Ojasa Mirai

Ojasa Mirai

Python

Loading...

Learning Level

🟢 Beginner🔵 Advanced
Classes & ObjectsMethods & SelfInstance VariablesClass VariablesConstructors & InitializationInheritance BasicsPolymorphismEncapsulationMagic Methods & Dunder
Python/Oop/Polymorphism

🔀 Polymorphism — Advanced Duck Typing and Generic Programming

Advanced polymorphism includes structural typing with protocols, generic programming with TypeVar, and sophisticated duck typing patterns. These techniques enable flexible, type-safe code without rigid class hierarchies.


🎯 Structural Subtyping with Protocols

Protocols define interfaces without requiring explicit inheritance. Any object with the right methods satisfies a protocol.

from typing import Protocol

class Drawable(Protocol):
    """Protocol for drawable objects"""
    def draw(self) -> str:
        ...

class Circle:
    def draw(self) -> str:
        return "Drawing circle"

class Square:
    def draw(self) -> str:
        return "Drawing square"

class Renderer:
    def render(self, drawable: Drawable) -> None:
        print(drawable.draw())

renderer = Renderer()
renderer.render(Circle())    # Works - Circle satisfies Drawable
renderer.render(Square())    # Works - Square satisfies Drawable

# No explicit inheritance needed!

🔤 Generic Programming with TypeVar

Use TypeVar for type-safe generic programming without losing flexibility.

from typing import TypeVar, Generic, List

T = TypeVar('T')

class Stack(Generic[T]):
    def __init__(self):
        self.items: List[T] = []

    def push(self, item: T) -> None:
        self.items.append(item)

    def pop(self) -> T:
        return self.items.pop()

    def is_empty(self) -> bool:
        return len(self.items) == 0

# Type-safe stack
int_stack: Stack[int] = Stack()
int_stack.push(1)
int_stack.push(2)
print(int_stack.pop())  # Type checker knows this is int

str_stack: Stack[str] = Stack()
str_stack.push("hello")
print(str_stack.pop())  # Type checker knows this is str

📋 Advanced Protocol Patterns

Create protocols for complex behaviors.

from typing import Protocol, Iterator

class Container(Protocol):
    """Objects that can be iterated"""
    def __iter__(self) -> Iterator:
        ...

    def __len__(self) -> int:
        ...

class CustomCollection:
    def __init__(self, data):
        self.data = data

    def __iter__(self):
        return iter(self.data)

    def __len__(self):
        return len(self.data)

def process_collection(col: Container) -> None:
    print(f"Length: {len(col)}")
    for item in col:
        print(f"Item: {item}")

collection = CustomCollection([1, 2, 3])
process_collection(collection)

🔄 Functional Polymorphism

Treat functions as first-class polymorphic objects.

from typing import Callable, Union

class Operation:
    def __init__(self, func: Callable[[int, int], int], name: str):
        self.func = func
        self.name = name

    def execute(self, a: int, b: int) -> int:
        result = self.func(a, b)
        print(f"{self.name}: {a} and {b} = {result}")
        return result

add = Operation(lambda x, y: x + y, "Add")
multiply = Operation(lambda x, y: x * y, "Multiply")
subtract = Operation(lambda x, y: x - y, "Subtract")

operations = [add, multiply, subtract]
for op in operations:
    op.execute(10, 5)

📚 Real-World Examples

Plugin System with Protocols

from typing import Protocol, List, Dict

class DataSource(Protocol):
    def fetch(self) -> List[Dict]:
        ...

class CSVDataSource:
    def fetch(self) -> List[Dict]:
        return [{"name": "Alice", "age": 25}]

class APIDataSource:
    def fetch(self) -> List[Dict]:
        return [{"name": "Bob", "age": 30}]

class DatabaseDataSource:
    def fetch(self) -> List[Dict]:
        return [{"name": "Charlie", "age": 35}]

class DataPipeline:
    def __init__(self, source: DataSource):
        self.source = source

    def process(self):
        data = self.source.fetch()
        return [item for item in data if item["age"] >= 25]

# Works with any DataSource
csv_pipeline = DataPipeline(CSVDataSource())
api_pipeline = DataPipeline(APIDataSource())
db_pipeline = DataPipeline(DatabaseDataSource())

print(csv_pipeline.process())
print(api_pipeline.process())

Generic Repository Pattern

from typing import TypeVar, Generic, List, Optional

T = TypeVar('T')

class Repository(Generic[T]):
    def __init__(self):
        self.items: List[T] = []

    def add(self, item: T) -> None:
        self.items.append(item)

    def get_all(self) -> List[T]:
        return self.items.copy()

    def find(self, predicate) -> Optional[T]:
        for item in self.items:
            if predicate(item):
                return item
        return None

class User:
    def __init__(self, id: int, name: str):
        self.id = id
        self.name = name

class Product:
    def __init__(self, id: int, name: str, price: float):
        self.id = id
        self.name = name
        self.price = price

# Type-safe repositories
user_repo: Repository[User] = Repository()
user_repo.add(User(1, "Alice"))
user_repo.add(User(2, "Bob"))

user = user_repo.find(lambda u: u.name == "Alice")
if user:
    print(f"Found: {user.name}")

product_repo: Repository[Product] = Repository()
product_repo.add(Product(1, "Laptop", 999.99))
product = product_repo.find(lambda p: p.price > 500)
if product:
    print(f"Expensive product: {product.name}")

✅ Key Takeaways

ConceptRemember
ProtocolStructural interface without inheritance
TypeVarGeneric type parameter for type safety
GenericBase class for generic types
Duck TypingObject capabilities matter, not type
Type HintsDocument and verify types
Structural SubtypingInterfaces based on structure, not names
Functional PolymorphismFunctions as polymorphic objects
FlexibilityAchieve polymorphism without rigid hierarchies

🔗 What's Next?

Continue with advanced encapsulation patterns.

Advanced: Encapsulation →


Ready to practice? Try challenges or explore more concepts


Resources

Python Docs

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

Courses

PythonFastapiReactJSCloud

© 2026 Ojasa Mirai. All rights reserved.

TwitterGitHubLinkedIn