Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonの抽象基底クラス(abc)の使い方を徹底解説

1つ以上の抽象メソッド(abstract method)を持つクラスは「抽象クラス」と呼ばれます。抽象メソッドとは、宣言のみが行われ、実装を持たないメソッドのことです。抽象クラスは直接インスタンス化することができず、その抽象メソッドは必ずサブクラス側で実装しなければなりません。

抽象基底クラス(ABC)とは

抽象基底クラス(Abstract Base Classes:ABC)は、hasattr() のような他の手法では不格好になったり、マジックメソッドの扱いなどで微妙に誤動作したりするケースにおいて、インターフェースを明確に定義するための手段を提供します。

ABCには「仮想サブクラス(virtual subclass)」という概念が導入されています。これは、あるクラスを継承していないにもかかわらず、isinstance() や issubclass() の判定ではその派生クラスとして認識されるクラスのことです。

Pythonには多くの組み込みABCが用意されています。Iterator、Generator、Set、Mapping などのデータ構造向けABCは collections.abc モジュールに定義されており、numbers モジュールには数値型のための基底クラス群(数値タワー)が定義されています。また、標準ライブラリの abc モジュールは、独自の抽象基底クラスを定義するための基盤を提供しています。

abcモジュールの基本的な仕組み

abc モジュールでは、基底クラスのメソッドを「抽象」としてマークすることで機能します。これを行うのが @abstractmethod デコレータです。抽象基底クラスのサブクラスである具象クラスは、抽象メソッドをオーバーライドして実装します。

ABCMetaを使った定義例

abc モジュールは、抽象基底クラスを定義するためのメタクラス ABCMeta を提供しています。次の例では、ABCMeta を使って Shape クラスを抽象基底クラスとして定義し、area() メソッドを @abstractmethod で装飾しています。

import abc
class Shape(metaclass=abc.ABCMeta):
   @abc.abstractmethod
   def area(self):
      pass
class Rectangle(Shape):
   def __init__(self, x,y):
      self.l = x
      self.b=y
   def area(self):
      return self.l*self.b
r = Rectangle(10,20)
print ('area: ',r.area())

複数の抽象メソッドがある場合の注意点

抽象基底クラスには複数の抽象メソッドを含めることもできます。この場合、子クラスはそれらすべてを実装しなければならず、1つでも未実装のままインスタンス化しようとすると TypeError が発生します。

ABCヘルパークラスの利用

abc モジュールには、抽象基底クラスの定義時に ABCMeta を直接指定する代わりに使えるヘルパークラス ABC も用意されています。こちらの方が記述がシンプルになります。

class Shape(abc.ABC):
   @abc.abstractmethod
   def area(self):
      pass

register()による仮想サブクラスの登録

抽象基底クラスを継承する代わりに、register クラスデコレータを使えば、既存のクラスを抽象基底クラスの仮想サブクラスとして登録できます。

class Shape(abc.ABC):
   @abc.abstractmethod
   def area(self):
      pass
@Shape.register
class Rectangle():
   def __init__(self, x,y):
      self.l = x
      self.b=y
   def area(self):
      return self.l*self.b

クラスメソッド・スタティックメソッドの抽象化

さらに、@abstractclassmethod および @abstractstaticmethod デコレータを使うことで、抽象基底クラス内でクラスメソッドやスタティックメソッドを抽象メソッドとして定義することも可能です。

  1. Pythonのクラスと継承を徹底解説!基本構文からコード例まで

    オブジェクト指向プログラミングは、プロジェクト内のコード重複(冗長化)を防ぐために、再利用可能なコードパターンを作成する手法です。その再利用性を実現する手段のひとつが継承(インヘリタンス)であり、サブクラスが基底クラスのコードを活用できる仕組みを指します。 継承とは何か 継承とは、あるクラスが別のクラス内に記述されたコードを引き継いで利用できるようにする仕組みです。 子クラス(サブクラス)と呼ばれるクラスは、親クラス(基底クラス)からメソッドや変数を受け継ぎます。 ChildサブクラスがParent基底クラスを継承している場合、ChildクラスはParentクラスのコードをそのまま再利用でき

  2. Pythonでクラスを定義する方法を解説!基本構文と書き方のポイント

    Pythonでは、ほぼすべてのコードがクラスを使って実装されています。プログラマーはクラスを利用することで、関連性の高いコードをひとつにまとめて管理できます。これは「class」というキーワードによって実現されており、クラスはオブジェクト指向プログラミングの構成要素を集約したものです。クラスとは何かクラスとは、オブジェクト(インスタンス)を生成するための設計図・テンプレートです。オブジェクトはメンバー変数(属性)を持ち、それに関連付けられた振る舞い(メソッド)を備えています。Pythonでは、classキーワードを使うことでクラスを作成します。基本的なクラスの定義方法まずは、関数やメソッドを一