100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Python

Abstraction in Python

How Python hides implementation complexity behind simple interfaces, using the abc module to enforce required methods.

OOP BasicsIntermediate9 min readJul 7, 2026
Analogies

1. Introduction

Abstraction is the OOP principle of exposing only the essential features of an object while hiding the internal implementation details. It lets users of a class interact with a simple, well-defined interface — calling methods like start() or area() — without needing to know how those methods are implemented internally.

🏏

Cricket analogy: A batsman just needs to know 'press the trigger and swing' — the biomechanics of bat-speed and wrist rotation stay hidden, exactly like abstraction exposing only start() or area() while hiding internals.

In Python, abstraction is commonly achieved using Abstract Base Classes (ABCs) from the built-in abc module. An ABC defines a required interface (a set of abstract methods) that concrete subclasses must implement, without providing (or requiring) a full implementation itself.

🏏

Cricket analogy: Just as every state team in the Ranji Trophy must field a wicketkeeper and an opening pair by rule, an abstract Shape class forces every subclass to implement area() and perimeter(), flagging a missing one immediately rather than failing mid-match.

2. Syntax

python
from abc import ABC, abstractmethod


class Shape(ABC):
    @abstractmethod
    def area(self):
        pass          # no implementation here — subclasses MUST override

    def describe(self):
        return f"This shape has area {self.area()}"


class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):    # required override
        return 3.14159 * self.radius ** 2

3. Explanation

A class becomes an ABC by inheriting from ABC (or using ABCMeta as its metaclass) and marking one or more methods with @abstractmethod. Python then prevents you from instantiating the ABC directly, and it prevents instantiating any subclass that hasn't overridden every abstract method. This enforces the abstraction contract at instantiation time, which is stronger than a plain raise NotImplementedError convention.

🏏

Cricket analogy: The BCCI doesn't just post a rulebook saying captains 'should' know DRS review strategy — it actively bars uncertified captains from the toss, just as Python's ABC actively blocks instantiation rather than relying on a NotImplementedError convention.

Abstract classes can still provide concrete (fully implemented) methods alongside abstract ones — like describe() in the example — letting subclasses inherit shared logic while being forced to supply the pieces that must vary (area()).

🏏

Cricket analogy: A team's fixed post-match press-conference format (concrete method) is shared by every captain, but each must still supply their own answer to 'what's your strategy for the next match?' (abstract method), just like describe() reusing logic while area() must vary.

Abstraction and encapsulation are related but distinct: encapsulation hides internal data/state and controls access to it (e.g., via @property), while abstraction hides implementation complexity and exposes only a simplified, essential interface (e.g., via ABCs). A well-designed class typically uses both together: an abstract, minimal public interface backed by encapsulated, protected internal state.

Attempting to instantiate an ABC that has unimplemented abstract methods raises TypeError: Can't instantiate abstract class ... with abstract methods .... This is different from the softer, convention-based NotImplementedError pattern, which only fails when the unimplemented method is actually called, not at instantiation time — always prefer abc.ABC when you want the contract enforced early.

4. Example

python
from abc import ABC, abstractmethod


class PaymentMethod(ABC):
    @abstractmethod
    def pay(self, amount):
        pass

    def receipt(self, amount):
        return f"Paid {amount} via {self.__class__.__name__}: {self.pay(amount)}"


class CreditCard(PaymentMethod):
    def pay(self, amount):
        return f"charged ${amount} to credit card"


class UPI(PaymentMethod):
    def pay(self, amount):
        return f"transferred ${amount} via UPI"


for method in [CreditCard(), UPI()]:
    print(method.receipt(50))

try:
    generic = PaymentMethod()
except TypeError as e:
    print("Error:", e)

5. Output

text
Paid 50 via CreditCard: charged $50 to credit card
Paid 50 via UPI: transferred $50 via UPI
Error: Can't instantiate abstract class PaymentMethod with abstract method pay

6. Key Takeaways

  • Abstraction hides implementation complexity behind a simple, essential public interface.
  • The abc module's ABC and @abstractmethod define required methods concrete subclasses must implement.
  • Python raises a TypeError if you try to instantiate an ABC (or an incomplete subclass) directly.
  • Abstract classes can mix abstract methods with fully implemented concrete methods.
  • Abstraction (hiding complexity) and encapsulation (hiding/protecting data) work together but address different concerns.

Practice what you learned

Was this page helpful?

Topics covered

#Python#PythonProgrammingStudyNotes#Programming#AbstractionInPython#Abstraction#Syntax#Explanation#Example#OOP#StudyNotes#SkillVeris