Comme expliqué dans les autres réponses, oui, vous pouvez utiliser des classes abstraites en Python en utilisant le abc
module . Ci - dessous je donne un exemple réel à l' aide abstraite @classmethod
, @property
et @abstractmethod
( en utilisant Python 3.6+). Pour moi, il est généralement plus facile de commencer avec des exemples que je peux facilement copier et coller; J'espère que cette réponse est également utile pour d'autres.
Créons d'abord une classe de base appelée 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
Notre Base
classe aura toujours un from_dict
classmethod
, un property
prop1
(qui est en lecture seule) et un property
prop2
(qui peut également être défini) ainsi qu'une fonction appelée do_stuff
. Quelle que soit la classe qui est maintenant construite, elle Base
devra implémenter tout cela pour les méthodes / propriétés. Veuillez noter que pour qu'une méthode soit abstraite, deux décorateurs sont requis - classmethod
et abstraits property
.
Maintenant, nous pourrions créer une classe A
comme celle-ci:
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')
Toutes les méthodes / propriétés requises sont implémentées et nous pouvons - bien sûr - également ajouter des fonctions supplémentaires qui ne font pas partie Base
(ici:) i_am_not_abstract
.
Maintenant, nous pouvons faire:
a1 = A('dummy', 10, 'stuff')
a2 = A.from_dict({'name': 'from_d', 'val1': 20, 'val2': 'stuff'})
a1.prop1
# prints 10
a1.prop2
# prints 'stuff'
Comme souhaité, nous ne pouvons pas définir prop1
:
a.prop1 = 100
reviendra
AttributeError: impossible de définir l'attribut
Notre from_dict
méthode fonctionne également très bien:
a2.prop1
# prints 20
Si nous définissons maintenant une deuxième classe B
comme celle-ci:
class B(Base):
def __init__(self, name):
self.name = name
@property
def prop1(self):
return self.name
et a essayé d'instancier un objet comme celui-ci:
b = B('iwillfail')
nous obtiendrons une erreur
TypeError: Impossible d'instancier la classe abstraite B avec les méthodes abstraites do_stuff, from_dict, prop2
répertoriant toutes les choses définies dans Base
lesquelles nous n'avons pas implémenté B
.