0% found this document useful (0 votes)
2 views19 pages

1 - Abstract Classess Python

The document provides an in-depth exploration of abstraction in Object-Oriented Programming (OOP) with a focus on Python, specifically discussing Abstract Base Classes (ABCs), abstract methods, and the abc module. It emphasizes the importance of enforcing interface contracts, enabling polymorphism, and designing scalable software systems while highlighting the evolution, advantages, and disadvantages of using ABCs. Additionally, it includes practical examples, use cases, and design considerations for implementing abstraction in Python.

Uploaded by

rajutarun562
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views19 pages

1 - Abstract Classess Python

The document provides an in-depth exploration of abstraction in Object-Oriented Programming (OOP) with a focus on Python, specifically discussing Abstract Base Classes (ABCs), abstract methods, and the abc module. It emphasizes the importance of enforcing interface contracts, enabling polymorphism, and designing scalable software systems while highlighting the evolution, advantages, and disadvantages of using ABCs. Additionally, it includes practical examples, use cases, and design considerations for implementing abstraction in Python.

Uploaded by

rajutarun562
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Abstraction in Object-

Oriented Programming
PYTHON FOCUS INTERMEDIATE LEVEL

A deep dive into Abstract Base Classes, abstract methods, and the abc
module — the tools Python provides to enforce interface contracts, enable
polymorphism, and design robust, scalable software systems.
Topic Classification

Category
Object-Oriented Programming /
Design Principle

Difficulty
Intermediate — requires knowledge
of classes, inheritance,
polymorphism, and Python
decorators

Industry Relevance
Core to Django, Flask, SQLAlchemy,
plugin systems, testing (mocking),
and framework development

Recommended Path
Python Classes → Inheritance &
super() → Polymorphism →
Abstraction (ABCs) → Protocols →
Design Patterns
What Is Abstraction?
Abstraction in Python is the OOP principle of hiding implementation details and exposing only essential features. Python
implements abstraction through Abstract Base Classes (ABCs) using the abc module.

Define Interfaces Enforce Contracts Enable Polymorphism


Specify what a class must do, not Derived classes must implement Use base class references to invoke
how it does it. abstract methods — raises TypeError derived implementations seamlessly.
otherwise.

Prevent Instantiation Open/Closed Principle


Stops creation of incomplete or logically meaningless base Extend behaviour by adding new subclasses without
class objects. modifying existing code.

Think of a Vehicle — you know every vehicle can start() and stop(), but a generic "Vehicle" doesn't exist in the real world. You
program to the Vehicle interface, not to the concrete details.
Key Terminology
Abstract Base Class (ABC) A class inheriting from [Link] that cannot be instantiated.

Abstract method A method decorated with @abstractmethod; has no implementation in the abstract
class.

Concrete class A subclass that overrides all abstract methods; can be instantiated.

abc module Python's built-in module for defining abstract base classes.

@abstractmethod Decorator that marks a method as abstract.

Duck typing Python's dynamic approach to interfaces; ABCs provide an explicit alternative.

Virtual subclass A class registered via register() as an ABC subclass without explicit inheritance.

Concrete implementation A class that provides definitions for all inherited abstract methods.

Declare
Define Implement in Instantiate
Import ABC @abstractme
Abstract Subclass Concrete
thod

These five steps form the complete lifecycle of working with Abstract Base Classes in Python — from import to instantiation.
Why Does Abstraction Exist?
Problems It Solves What Happens Without ABCs?

Incomplete base classes


Duck Typing Documentation
Prevents creating objects of a class that logically should Only
No formal enforcement
not exist (e.g., a bare Shape).
— runtime AttributeError Human-readable
if method is missing. contracts only — easy to
Interface specification violate accidentally.

Forces subclasses to adhere to a contract; TypeError


raised if contract is violated.
NotImplementedErr Custom
or Metaclasses
Machine-checkable docs
Runtime check only — Overkill for most use
Makes the intended interface explicit and verifiable by
not caught at class cases; complex and
Python itself.
creation time. error-prone.

Polymorphic collections
Store instances of concrete subclasses in a container ABCs provide an explicit, enforceable contract at

typed to the abstract base. class definition time — the best of all worlds.
Evolution & History
1990s 1
Python early versions had no formal ABCs; duck
typing was the norm.

2 2000–2005
PEP 245 (Interface Syntax) rejected. Python 2.2
introduced the NotImplementedError convention.
2007 3
PEP 3119 — Introducing Abstract Base Classes.
Implemented in Python 2.6 and 3.0.
4 2008–2012
abc module added; collections gains ABCs for
containers (Iterable, Sequence, MutableMapping).
2015–2020 5
@abstractmethod works with @property,
@classmethod, @staticmethod. Type checkers (mypy)
recognise ABCs. 6 Present
ABCs stable and widely used. PEP 544 introduces
Protocol for structural subtyping, complementing
ABCs.

Approach Limitation

Duck typing No compile-time enforcement; errors occur at runtime, possibly deep in code.

Raising NotImplementedError Only checked when method is called, not at class definition.

Manual documentation Not machine-checkable.

Zope interfaces (external) Non-standard, complex, requires third-party dependency.


How It Works: Python Internals
Simple Example

from abc import ABC,


abstractmethod

class Animal(ABC):
@abstractmethod
def speak(self):
pass

# TypeError: Can't instantiate


# a = Animal()

Metaclass Magic — ABCMeta class Dog(Animal):


def speak(self):
When a class inherits from ABC, it gains a metaclass (ABCMeta). This metaclass: return "Woof!"

Tracks which methods are marked as abstract


d = Dog() # OK
Prevents instantiation if any abstract methods remain unimplemented
print([Link]()) # Woof!
Raises TypeError when a subclass fails to override all abstract methods

Abstract Methods Can Have


Bodies

class Base(ABC):
@abstractmethod
def greet(self):
Mark Collect print("Base greeting")
Subclass
Define ABC Use ABCMeta @abstractme abstractmeth
overrides
thod ods
class Derived(Base):
def greet(self):
This internal mechanism ensures contracts are enforced at the earliest possible
super().greet()
moment — class creation, not method call time.
print("Derived greeting")

d = Derived()
[Link]()
# Base greeting
# Derived greeting

In Python, @abstractmethod can


have a body. Subclasses must
still override it, but can call
super() to access the base
implementation.
Types & Variants of Abstraction in Python

Pure ABC (Interface) ABC with Partial ABC with Abstract Properties
Only abstract methods, no concrete
Implementation Enforces property getters/setters.
methods or data. Forces full Mix of abstract and concrete Ideal for data validation and
implementation. Clean contract methods. Enables the Template computed attributes. Slightly more
definition. Method pattern and framework verbose.
hooks with code reuse.

ABC with __subclasshook__ Virtual Subclass


Allows duck-typing to be recognised as a subclass. Using register() to mark an existing class as an ABC
Retroactive registration without inheritance. Use sparingly. subclass. Works with third-party classes. No method
guarantee.

Feature Pure Interface Partial Impl. Abstract Properties Virtual Subclass

Concrete methods No Yes Maybe No (external class)

Forced implementation Yes Only abstract Yes No (registration doesn't


check)

Typical pattern Strategy, Template Property-based Adapting external libraries


Command Method interfaces
Real-World Use Cases

Django Abstract Models Custom Container Plugin System with Runtime


Define a TimeStampedModel abstract
(MutableSequence) Discovery
base class with created_at and Subclass A CI/CD tool loads plugins from a
updated_at fields. 15 models reused the [Link] to directory. Each plugin must implement
same timestamp logic — DRY principle in create a LoggingList that logs every run(), name(), and validate(). The Plugin
action. Django uses Meta: abstract = True access. Implement just 5 abstract ABC prevents loading incomplete plugins
rather than [Link], but the principle is methods (__getitem__, __setitem__, — TypeError raised early. Result: zero
identical. __delitem__, __len__, insert) and gain 20+ runtime method-missing errors across 40
methods for free. 200 lines instead of plugins.
500.
Implementations & Code Examples
Implementation 1: Employee Hierarchy Implementation 2: Abstract Properties & Class
Methods
from abc import ABC, abstractmethod
from abc import ABC, abstractmethod
class Employee(ABC):
def __init__(self, name: str): class ConfigSource(ABC):
[Link] = name @property
@abstractmethod
@abstractmethod def connection_string(self) -> str:
def calculate_salary(self) -> float: pass
pass
@classmethod
@abstractmethod @abstractmethod
def role_description(self) -> str: def from_env(cls) -> "ConfigSource":
pass pass

def common_benefits(self) -> str: class FileConfig(ConfigSource):


return "Health insurance + paid leave" def __init__(self, path: str):
self._path = path
class Developer(Employee):
def __init__(self, name, hourly_rate, hours): @property
super().__init__(name) def connection_string(self) -> str:
self.hourly_rate = hourly_rate return f"[Link]
[Link] = hours
@classmethod
def calculate_salary(self) -> float: def from_env(cls) -> "FileConfig":
return self.hourly_rate * [Link] import os
return cls([Link]("CONFIG_PATH",
def role_description(self) -> str: "/default/config"))
return "Writes code and fixes bugs"
fc = FileConfig("/etc/app/config")
class Manager(Employee): print(fc.connection_string)
def __init__(self, name, fixed_salary): # [Link]
super().__init__(name)
self.fixed_salary = fixed_salary
Implementation 3: Virtual Subclass via register()

def calculate_salary(self) -> float:


from abc import ABC, abstractmethod
return self.fixed_salary

class Drawable(ABC):
def role_description(self) -> str:
@abstractmethod
return "Manages team and projects"
def draw(self):
pass
emp1 = Developer("Alice", 50, 160)
emp2 = Manager("Bob", 8000)
class Point: # third-party, can't modify
print(emp1.calculate_salary()) # 8000.0
def draw(self):
print(emp2.role_description()) # Manages team and
print(f"Drawing point")
projects
# Employee() → TypeError [Link](Point)
p = Point(10, 20)
print(isinstance(p, Drawable)) # True
Hands-On Labs
1 2

Lab 1: Abstract Shape Calculator Lab 2: Playlist — a MutableSequence

BEGINNER INTERMEDIATE

Objective: Create an abstract Shape class with abstract Objective: Subclass [Link] to
methods area() and perimeter(). Implement Rectangle and create a Playlist class that logs every addition/removal.
Circle.
1. Import MutableSequence from [Link]
1. Import ABC and abstractmethod from abc 2. Define Playlist(MutableSequence) with self._items = []
2. Define Shape class inheriting ABC 3. Implement 5 required abstract methods with logging
3. Add @abstractmethod for area and perimeter print statements

4. Define Rectangle(width, height) and Circle(radius) 4. Test: create playlist, add songs, index, delete, append,
extend
5. Store instances in a list, iterate and print results
6. Try to instantiate Shape() — observe TypeError 5. Observe that append, extend, pop work automatically

Learning Outcome: Implementing 5 abstract methods


Expected: Rectangle(4,5): area=20, perimeter=18 |
Circle(3): area≈28.27, perimeter≈18.85 gives you a fully functional sequence type with 20+ list
methods for free.

from [Link] import MutableSequence

class Playlist(MutableSequence):
def __init__(self):
self._items = []

def __getitem__(self, index):


print(f"Accessing index {index}")
return self._items[index]

def __setitem__(self, index, value):


self._items[index] = value

def __delitem__(self, index):


del self._items[index]

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

def insert(self, index, value):


print(f"Inserting {value} at {index}")
self._items.insert(index, value)

p = Playlist()
[Link]("Song A") # uses insert internally
[Link]("Song B")
print(p[0]) # Accessing index 0 → Song A
Advantages & Disadvantages

✅ Enforces
Contracts
✅ Fail-Fast Safety ⚠️ Over- ⚠️ Learning Curve
Engineering Risk
Raises TypeError early at Requires understanding
Prevents incomplete class definition or Can lead to unnecessary ABC syntax, decorators,
objects; supports instantiation. complexity for simple and metaclasses.
Open/Closed Principle. scripts.

✅ Machine-
Checkable Docs
✅ Code Reuse ⚠️ Virtual Subclass ⚠️ Deep
Risk Hierarchies
ABCs can provide
Abstract methods act as concrete methods that all Virtual subclasses do not May encourage deep
clear, verifiable subclasses inherit. enforce method inheritance chains that
documentation. presence — use are hard to maintain.
carefully.

✅ Minimal Overhead
Abstract method check occurs only once at instantiation
⚠️ Breaking Changes
— no per-call cost. Adding abstract methods to a published ABC breaks all
existing subclasses.

Balanced View: Use ABCs for frameworks, plugins, and public APIs. Consider Protocols (PEP 544) for static type
checking without runtime overhead. Avoid ABCs for simple internal scripts where duck typing suffices.
Performance & Scalability
Performance Characteristics Scalability in Codebases

Negligible Runtime One-Time Check Scales Well Breaking API Change


Overhead
The abstractness check Adding new concrete Adding a new abstract
ABCs add no extra occurs only once when the subclasses does not affect method to an existing ABC
indirection beyond normal class is instantiated or existing code using the breaks all existing
inheritance for method when a subclass is ABC. Open/Closed concrete subclasses until
calls. No per-call cost created. Principle in action. they override it.
whatsoever.

Backward Reliability
Minimal Memory Impact Compatibility
Fail-fast behaviour catches
The __abstractmethods__ frozenset is stored on the class Alternatives: add a new errors early. Virtual
object — negligible memory footprint. versioned ABC, or provide subclasses bypass method
a mixin with a default checking — use sparingly
implementation to avoid to avoid runtime
Guideline: Use ABCs freely — they will never be your
breaking changes. AttributeError.
performance bottleneck. Object creation and
attribute lookup overhead far outweighs any ABC
checks.
Design & Architectural Considerations
Template Method
1
ABC defines skeleton algorithm with abstract steps. Subclasses fill in the blanks.

Factory Method
2
Abstract creator declares factory method. Concrete creators return specific product types.

Strategy
3
ABC defines strategy interface. Concrete strategies implement interchangeable algorithms.

Command
4
ABC defines execute() method. Commands encapsulate actions as objects.

Observer
5
ABC defines update() method. Observers react to state changes in subjects.

Decision Options Recommendation

Pure ABC vs partial Only abstract / mix of abstract and Pure ABC for interfaces; partial for
implementation concrete Template Method

Virtual subclassing vs explicit register() vs normal subclass Prefer explicit; register only for third-
inheritance party classes

ABC vs Protocol (PEP 544) Runtime enforcement / static checking ABC for runtime isinstance; Protocol for
only static typing

__subclasshook__ Custom recognition logic Use sparingly — can lead to surprising


behaviour
Security Considerations

Concer Description Mitigati


n on

Instanti Could a Rely on


ation user Python'
bypass instantiate s built-
an ABC by in
hacking enforce
__new__? ment.
Unlikely —
ABCMeta
prevents it.

Virtual Malicious Trust


subclas code could bounda
s register an ry: if
registra incompatibl you
tion e class as control
virtual registra
subclass, tion, it's
causing safe.
isinstance to
lie.

Method ABCs do Use


overridi not enforce type
ng method annotati
signature — ons and
only the static
method analysis
name. A (mypy).
subclass
could
override
with wrong
parameters.

Best Practice: For security-


sensitive code, combine ABCs
with type checking and
validation of method signatures
at runtime using
[Link].
Best Practices
✅ Do's ❌ Don'ts
Design with ABCs for large systems Don't over-engineer simple scripts
Use ABCs to define clear interfaces for libraries and Duck typing is sufficient for small scripts with few
frameworks where multiple teams develop against classes. ABCs add boilerplate without benefit.
stable contracts.

Don't forget @abstractmethod


Always inherit from ABC
Without the decorator, the method is concrete — the
Use class MyABC(ABC): or set metaclass=ABCMeta class can be instantiated even if the method body is just
explicitly — never rely on @abstractmethod alone. pass.

Document abstract methods Don't add abstract methods to published


ABCs
Write docstrings explaining the purpose and required
behaviour of each abstract method. This is a breaking change. Provide a default
implementation or create a new versioned ABC instead.

Use type hints


Don't use deprecated @abstractproperty
Add type annotations to abstract methods for better
static checking with mypy. Use @property + @abstractmethod stacked together
instead.
Common Mistakes & Pitfalls
1 2 3

Forgetting to inherit from ABC Misspelling the abstract Using deprecated


Why: Unaware that method name @abstractproperty
@abstractmethod alone doesn't Why: Typo in subclass override. Why: Old tutorials or legacy code.
enforce abstractness. Impact: Abstract method remains Impact: Still works but may be
Impact: Class can be instantiated abstract; subclass still cannot be removed in future Python versions.
even with abstract methods. instantiated. Fix: Stack @property and
Fix: Always use class MyClass(ABC): Fix: Use IDE autocomplete or check @abstractmethod decorators.
or metaclass=ABCMeta. __abstractmethods__ attribute.

4 5

Registering virtual subclass without Defining __subclasshook__ incorrectly


implementing methods Why: Complex logic errors.
Why: Over-optimism about duck typing. Impact: Unexpected issubclass results that are hard to
Impact: isinstance returns True but method calls fail at debug.
runtime. Fix: Prefer explicit inheritance over __subclasshook__
Fix: Ensure registered class actually implements the full whenever possible.
interface.
Comparison with Alternatives
ABCs vs Protocols vs Duck Typing vs When to Choose What
NotImplementedError
Library API with Large project with
Feature ABC Proto Duck NotI runtime type mypy
col Typin mple checking
g ment → Protocols: More
edErr → ABCs: isinstance flexible, no inheritance
or works and enforces at needed.
creation.
Runtime Yes No No No
isinstance
Quick script, small Backward
Static type Yes Yes Partia No team compatibility
checking (mypy l
→ Duck typing: Simple, → NotImplementedError:
)
no boilerplate. Least disruptive but least

Enforcement Yes N/A No No safe — refactor when

at class possible.

definition

Performance Minim Zero Zero Zero


overhead al

Intent clarity High Moder Low Low


ate

Third-party Via Struct Alway Requi


class support registe ural s res
r() match subcl
assin
g

Python vs Java vs C++

Aspect Python Java C++

Keyword No abstract =0
keyword
(use ABC)

Multiple Yes Interfaces Yes


inheritance (ABCs only
support)

Abstract Yes No Yes (pure


method with (allowed) virtual)
body

Runtime isinstance instanceof dynamic_


interface (obj, ABC) cast
check

Metaclass Yes No No
support (ABCMeta
)
Learning Summary & Key Takeaways
01 02 03

ABCs are defined with [Link] Subclasses must override all ABCs support concrete methods,
and @abstractmethod abstract methods properties, and class/static
A class with at least one abstract method Only then do they become concrete and
methods
cannot be instantiated — TypeError is instantiable. Partial overrides keep the They are not limited to pure interfaces —
raised. subclass abstract. they can provide shared implementations
too.

04 05

Use ABCs for frameworks, plugins, and large Virtual subclasses and __subclasshook__ enable
codebases duck-typing compatibility
For static type checking without runtime overhead, consider Use sparingly — they bypass method enforcement and can lead
Protocols (PEP 544) instead. to surprising runtime errors.

from abc import ABC, abstractmethod

class AbstractClassName(ABC):
@abstractmethod
def required_method(self):
"""Must be overridden"""
pass

def concrete_method(self):
return "shared implementation"

class ConcreteClass(AbstractClassName):
def required_method(self):
return "implementation"

obj = ConcreteClass() # OK
# base = AbstractClassName() # TypeError

Next: Protocols (PEP 544) Next: Metaclasses Next: Design Patterns


Static duck typing without ABCMeta is a metaclass — deepen Template Method, Strategy,
inheritance. your ABC knowledge. Command — all leverage ABCs.

Next: [Link] Next: Type Hints & mypy


Practical ABCs for containers, iterators, and callables. Static typing complements ABCs for large codebases.

You might also like