Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprende Defining ABCs with the abc Module | The Foundations of ABCs
Python Abstract Base Classes

Defining ABCs with the abc Module

Desliza para mostrar el menú

Python's abc module provides two ways to define an abstract base class: inheriting from ABC or using ABCMeta as a metaclass directly. Both achieve the same result – the choice is mostly stylistic.

Inheriting from ABC

The simplest approach is to inherit from abc.ABC. This automatically sets ABCMeta as the metaclass:

1234567891011121314151617181920212223
from abc import ABC, abstractmethod # Defining an ABC by inheriting from ABC class PaymentProcessor(ABC): @abstractmethod def process(self, amount): pass @abstractmethod def refund(self, transaction_id): pass # Concrete implementation class StripeProcessor(PaymentProcessor): def process(self, amount): return f"Stripe: processing ${amount:.2f}" def refund(self, transaction_id): return f"Stripe: refunding {transaction_id}" processor = StripeProcessor() print(processor.process(99.99)) print(processor.refund("TXN-001"))

Using ABCMeta Directly

ABCMeta is the metaclass that powers ABCs. Inheriting from ABC is shorthand for setting metaclass=ABCMeta. Both are equivalent:

1234567891011
from abc import ABCMeta, abstractmethod # Using ABCMeta directly – equivalent to inheriting from ABC class PaymentProcessor(metaclass=ABCMeta): @abstractmethod def process(self, amount): pass @abstractmethod def refund(self, transaction_id): pass

Use ABC inheritance in almost all cases – it is cleaner and more readable. Use ABCMeta directly only when your class already inherits from another class that uses a different metaclass.

Inspecting Abstract Methods

__abstractmethods__ is a frozenset of method names that must be implemented before the class can be instantiated:

1234567891011121314151617
from abc import ABC, abstractmethod class ReportGenerator(ABC): @abstractmethod def generate(self, data): pass @abstractmethod def format_output(self, report): pass def save(self, path, content): with open(path, "w") as output_file: output_file.write(content) # Inspecting which methods are abstract print(ReportGenerator.__abstractmethods__) # frozenset({'generate', 'format_output'})

save is not abstract – it is a concrete method and does not appear in __abstractmethods__.

Partial Implementation

A subclass that implements only some abstract methods is itself abstract and cannot be instantiated:

1234567891011121314151617181920212223
from abc import ABC, abstractmethod class DataPipeline(ABC): @abstractmethod def extract(self): pass @abstractmethod def transform(self, data): pass @abstractmethod def load(self, data): pass # Partial implementation – still abstract class ExtractOnlyPipeline(DataPipeline): def extract(self): return [{"id": 1, "value": 100}, {"id": 2, "value": 200}] print(ExtractOnlyPipeline.__abstractmethods__) # frozenset({'transform', 'load'}) pipeline = ExtractOnlyPipeline() # TypeError – transform and load not implemented

This allows building intermediate abstract classes in a hierarchy – each layer can implement some methods while leaving others for deeper subclasses.

question mark

What does __abstractmethods__ contain on an abstract class?

Selecciona la respuesta correcta

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 1. Capítulo 2

Pregunte a AI

expand

Pregunte a AI

ChatGPT

Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla

Sección 1. Capítulo 2
some-alt