Pythonのcollections.abcで学ぶコンテナの抽象基底クラス
Pythonには、コンテナ型のための抽象基底クラス(Abstract Base Classes: ABC)が標準ライブラリとして用意されています。これらは collections.abc モジュールにまとめられており、Container、Hashable、Generator、Set、MutableSet、Awaitable など、さまざまな抽象基底クラスが定義されています。
collections.abcモジュールのインポート
このモジュールを使用するには、まず次のようにインポートします。
import collections.abc
抽象基底クラスの活用例
抽象基底クラスは、独自のコンテナクラスを開発する際に非常に役立ちます。たとえば、セット(集合)としての完全な機能を持つコンテナを作成したい場合、Set 抽象基底クラスを継承するだけで実現できます。
このとき、自作クラス側で実装が必要なメソッドは主に次の3つです。
__contains__():指定した要素が含まれているかを判定する__iter__():イテレータを返す__len__():要素数を返す
これらの特殊メソッドさえ用意すれば、& 演算子による積集合の計算など、Set クラスが提供する豊富な演算機能をそのまま利用できるようになります。
サンプルコード
以下は、リストを内部に持つ独自のセットクラス ListSet を、collections.abc.Set を継承して実装した例です。
import collections.abc
class ListSet(collections.abc.Set):
def __init__(self, iterable):
self.elements = lst = list()
for element in iterable:
if element not in lst:
lst.append(element)
def __iter__(self):
return iter(self.elements)
def __contains__(self, value):
return value in self.elements
def __len__(self):
return len(self.elements)
set1 = ListSet('ABCDEF')
set2 = ListSet('DEFGHI')
intersect = set1 & set2
intersect_iter = iter(intersect)
try:
while True:
print(next(intersect_iter))
except StopIteration:
pass実行結果
このコードでは、'ABCDEF' と 'DEFGHI' の共通要素(積集合)を求め、順番に出力しています。
D E F
ポイント解説
ListSetは重複しないようにリストへ要素を追加することで、セットの性質を実現しています。set1 & set2のような演算子による操作は、Set抽象基底クラスが提供するミックスインメソッドによって自動的に使えるようになります。- イテレーションは
next()を使って手動で進めており、要素が尽きた時点で発生するStopIterationを捕捉してループを終了させています。
このように抽象基底クラスを継承すると、最小限のメソッド実装だけで、Python標準のセットと同等の振る舞いを持つ独自コンテナを簡潔に構築できます。
-
【Python入門】有向グラフにサイクル(閉路)が存在するかを検出するプログラムの作り方
本記事では、「与えられた有向グラフの中にサイクル(閉路)が存在するかどうかを判定する」という問題を、Pythonを使って解決する方法を解説します。 問題の概要 問題文: 有向グラフが与えられたとき、そのグラフにサイクルが含まれているかどうかを判定してください。少なくとも1つのサイクルが存在する場合は True を、存在しない場合は False を出力します。 この問題は、グラフ理論における基本的かつ重要なトピックの一つです。例えば、タスクのスケジューリングや依存関係の管理において、循環参照(デッドロック)を検出する場面などで応用されます。 判定には深さ優先探索(DFS)を利用します。ポイントは
-
Pythonの継承とは?単一継承と階層継承の基本をサンプルコードで解説
本記事では、Python 3.xにおける継承(インヘリタンス)とクラスの拡張方法について詳しく解説します。 継承とは、現実世界のモノや概念の関係性を自然に表現できる、オブジェクト指向プログラミングの中核となる仕組みです。継承を活用すると、次のようなメリットが得られます。 再利用性:すでに書いたコードを流用でき、重複を削減できる 推移性:クラス間の関係を連鎖的に引き継げる 開発速度の向上:ゼロから書かずに済むため、短期間で開発できる 保守性・拡張性:既存クラスを壊さずに機能を追加しやすい 継承の5つの種類 Pythonの継承は、その構造によって主に以下の5種類に分類されます。 単一継承(