他の回答で説明したように、はい、abc
モジュールを使用してPythonで抽象クラスを使用できます。私は、抽象使って、実際の例を与えるの下@classmethod
、@property
および@abstractmethod
(3.6以降のPythonを使用して)。私にとっては、通常、簡単にコピーして貼り付けることができる例から始める方が簡単です。この答えが他の人にも役立つことを願っています。
まず、次の基本クラスを作成しますBase
。
from abc import ABC, abstractmethod
class Base(ABC):
@classmethod
@abstractmethod
def from_dict(cls, d):
pass
@property
@abstractmethod
def prop1(self):
pass
@property
@abstractmethod
def prop2(self):
pass
@prop2.setter
@abstractmethod
def prop2(self, val):
pass
@abstractmethod
def do_stuff(self):
pass
私たちのBase
クラスには常に、、from_dict
classmethod
a property
prop1
(読み取り専用)、a property
prop2
(設定も可能)と呼ばれる関数がありdo_stuff
ます。現在基づいて構築されているクラスはBase
、メソッド/プロパティに対してこれらすべてを実装する必要があります。メソッドを抽象化するには、2つのデコレータが必要であることに注意してください- classmethod
とabstract property
です。
これで、次のA
ようなクラスを作成できます。
class A(Base):
def __init__(self, name, val1, val2):
self.name = name
self.__val1 = val1
self._val2 = val2
@classmethod
def from_dict(cls, d):
name = d['name']
val1 = d['val1']
val2 = d['val2']
return cls(name, val1, val2)
@property
def prop1(self):
return self.__val1
@property
def prop2(self):
return self._val2
@prop2.setter
def prop2(self, value):
self._val2 = value
def do_stuff(self):
print('juhu!')
def i_am_not_abstract(self):
print('I can be customized')
必要なすべてのメソッド/プロパティが実装されており、もちろんBase
(ここではi_am_not_abstract
)の一部ではない追加の関数を追加することもできます。
今私たちはできる:
a1 = A('dummy', 10, 'stuff')
a2 = A.from_dict({'name': 'from_d', 'val1': 20, 'val2': 'stuff'})
a1.prop1
# prints 10
a1.prop2
# prints 'stuff'
必要に応じて、次の設定はできませんprop1
。
a.prop1 = 100
戻ります
AttributeError:属性を設定できません
また、私たちのfrom_dict
方法はうまくいきます:
a2.prop1
# prints 20
次のB
ような2番目のクラスを定義したとします。
class B(Base):
def __init__(self, name):
self.name = name
@property
def prop1(self):
return self.name
そして、このようなオブジェクトをインスタンス化しようとしました:
b = B('iwillfail')
エラーが発生します
TypeError:抽象メソッドBを抽象メソッドdo_stuff、from_dict、prop2でインスタンス化できません
でBase
実装していない定義済みのものをすべてリストしB
ます。