Python でクラスまたはメソッドを抽象化するにはどうすればよいですか?
次のように再定義してみました__new__()
:
class F:
def __new__(cls):
raise Exception("Unable to create an instance of abstract class %s" %cls)
しかし、次のようG
に継承するクラスを作成すると、F
class G(F):
pass
G
次に、スーパークラスのメソッドを呼び出すため、インスタンス化もできません__new__
。
抽象クラスを定義するより良い方法はありますか?
ベストアンサー1
使用abc
抽象クラスを作成するためのモジュールです。abstractmethod
デコレータを使用してメソッドを抽象化して宣言し、Python のバージョンに応じて 3 つの方法のいずれかを使用してクラスを抽象化して宣言します。
Python 3.4以降では、ABC
以前のバージョンのPythonでは、クラスのメタクラスを次のように指定する必要がありました。ABCMeta
メタクラスの指定には、Python 3 と Python 2 で異なる構文があります。次の 3 つの可能性を示します。
# Python 3.4+
from abc import ABC, abstractmethod
class Abstract(ABC):
@abstractmethod
def foo(self):
pass
# Python 3.0+
from abc import ABCMeta, abstractmethod
class Abstract(metaclass=ABCMeta):
@abstractmethod
def foo(self):
pass
# Python 2
from abc import ABCMeta, abstractmethod
class Abstract:
__metaclass__ = ABCMeta
@abstractmethod
def foo(self):
pass
どちらの方法を使用する場合でも、抽象メソッドを持つ抽象クラスをインスタンス化することはできませんが、それらのメソッドの具体的な定義を提供するサブクラスをインスタンス化することはできます。
>>> Abstract()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Abstract with abstract methods foo
>>> class StillAbstract(Abstract):
... pass
...
>>> StillAbstract()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class StillAbstract with abstract methods foo
>>> class Concrete(Abstract):
... def foo(self):
... print('Hello, World')
...
>>> Concrete()
<__main__.Concrete object at 0x7fc935d28898>