Defining ABCs with the abc Module
メニューを表示するにはスワイプしてください
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:
1234567891011121314151617181920212223from 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:
1234567891011from 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:
1234567891011121314151617from 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:
1234567891011121314151617181920212223from 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.
フィードバックありがとうございます!
AIに質問する
AIに質問する
何でも質問するか、提案された質問の1つを試してチャットを始めてください