Unlike languages like Java / C#, Python does NOT have a dedicated interface keyword.
👉 Instead, Python achieves interface-like behavior using:
1. Abstract Base Classes (ABC)
2. Protocols (Structural Subtyping)
Python philosophy:
"We care about behavior, not rigid types"
An interface defines:
What an object MUST do
NOT how it does it
Think of it as a contract / blueprint
Interfaces help with:
✔ Loose coupling
✔ Scalable architecture
✔ Plug-in systems
✔ Clean API design
✔ Enforcing consistency
✔ Dependency inversion
| Concept | Purpose |
|---|---|
| Interface | Defines ONLY behavior |
| Abstract Class | Can define behavior + shared logic |
👉 Python blurs the line slightly.
Python’s traditional way to simulate interfaces.
from abc import ABC, abstractmethod
class PaymentProcessor(ABC):
@abstractmethod
def pay(self, amount):
passCannot instantiate:
p = PaymentProcessor() # ERROR class CreditCardProcessor(PaymentProcessor):
def pay(self, amount):
return f"Paid {amount} using Credit Card"processor = CreditCardProcessor()
print(processor.pay(100))Output:
Paid 100 using Credit Card
ABC behaves like:
Interface + Partial Implementation Capability
✔ Can contain logic
✔ Can contain attributes
✔ Can enforce methods
Introduced via:
from typing import ProtocolMajor difference:
Structural Typing ("Duck Typing with Rules")
| Typing Style | Meaning |
|---|---|
| Nominal Typing | Must explicitly inherit |
| Structural Typing | Must match structure |
👉 Python Protocols = Structural Typing
from typing import Protocol
class PaymentProcessor(Protocol):
def pay(self, amount: float) -> str:
...Now ANY class with pay() works
class UPIProcessor:
def pay(self, amount: float) -> str:
return f"Paid {amount} via UPI"✔ No inheritance
✔ Still valid interface match
def process_payment(processor: PaymentProcessor):
print(processor.pay(500))upi = UPIProcessor()
process_payment(upi)Output:
Paid 500 via UPI
Protocol checks:
Does object behave correctly?
NOT
Did object inherit correctly?
Pure Pythonic design
If you forget inheritance → No enforcement
Protocols are mainly for:
✔ Type checking tools (mypy / Pyright)
✔ Static analysis
Python itself won’t stop bad objects.
Matching method names ≠ Correct logic.
| Feature | ABC | Protocol |
|---|---|---|
| Requires Inheritance | ✅ Yes | ❌ No |
| Runtime Enforcement | ✅ Yes | ❌ No |
| Structural Typing | ❌ No | ✅ Yes |
| Pythonic Flexibility | Medium | Maximum 🔥 |
✔ You want strict enforcement
✔ Shared base logic needed
✔ Runtime safety required
✔ Framework design
✔ Flexibility needed
✔ Duck typing design
✔ Static typing benefits
✔ Plug-in architecture
✔ Large decoupled systems
Imagine:
Logging System
Any class with:
log(message)Should work.
Protocols shine here
Python prefers:
Behavioral Contracts
Over
Rigid Hierarchies
Interfaces in Python are:
✔ Lightweight
✔ Flexible
✔ Powerful
✔ Keep interfaces minimal
✔ Define behaviors only
✔ Avoid unnecessary abstraction
✔ Prefer Protocols for flexibility
✔ Use ABC for strict frameworks
✔ Don't over-engineer
✔ Python has no interface keyword
✔ ABC simulates classical interfaces
✔ Protocols enable structural typing
✔ ABC = Strict / Runtime Enforcement
✔ Protocol = Flexible / Static Typing
✔ Interfaces = Contracts
✔ Key for scalable design
- Create interface using ABC
- Try instantiating ABC (observe error)
- Implement subclass
- Add shared logic in ABC
- Create Protocol interface
- Implement class WITHOUT inheritance
- Use Protocol in function typing
- Compare ABC vs Protocol behavior