Как объяснено в других ответах, да, вы можете использовать абстрактные классы в Python, используя abc
модуль . Ниже я приведу конкретный пример , используя абстрактные @classmethod
, @property
и@abstractmethod
( с помощью Python 3.6 +). Для меня обычно легче начать с примеров, которые я могу легко скопировать и вставить; Я надеюсь, что этот ответ также полезен для других.
Давайте сначала создадим базовый класс с именем 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
класс всегда будет иметь a from_dict
classmethod
, a property
prop1
(который только для чтения) и a property
prop2
(который также может быть установлен), а также вызываемую функцию do_stuff
. Какой бы класс сейчас не был построен на основе Base
, придется реализовать все это для методов / свойств. Обратите внимание, что для абстрактного метода требуются два декоратора - classmethod
и абстрактный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
как это:
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
.