Як пояснено в інших відповідях, так, ви можете використовувати абстрактні класи в 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
.