Soyut temel sınıflarla arayüzler uygulamak modern Python 3'te çok daha basittir ve eklenti uzantıları için bir arayüz sözleşmesi olarak bir amaca hizmet ederler.
Interface / abstract base sınıfını oluşturun:
from abc import ABC, abstractmethod
class AccountingSystem(ABC):
@abstractmethod
def create_purchase_invoice(self, purchase):
pass
@abstractmethod
def create_sale_invoice(self, sale):
log.debug('Creating sale invoice', sale)
Normal bir alt sınıf oluşturun ve tüm soyut yöntemleri geçersiz kılın:
class GizmoAccountingSystem(AccountingSystem):
def create_purchase_invoice(self, purchase):
submit_to_gizmo_purchase_service(purchase)
def create_sale_invoice(self, sale):
super().create_sale_invoice(sale)
submit_to_gizmo_sale_service(sale)
İsteğe bağlı olarak, yukarıdaki gibi alt sınıfta açıkça create_sale_invoice()
çağırarak soyut yöntemlerde olduğu gibi ortak uygulamaya sahip olabilirsiniz super()
.
Tüm soyut yöntemleri uygulamayan bir alt sınıfın oluşturulması başarısız olur:
class IncompleteAccountingSystem(AccountingSystem):
pass
>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
İlgili ek açıklamaları bir araya getirerek soyut özelliklere, statik ve sınıf yöntemlerine de sahip olabilirsiniz @abstractmethod
.
Soyut temel sınıflar eklenti tabanlı sistemleri uygulamak için mükemmeldir. Bir sınıfın tüm içe aktarılan alt sınıflarına şu yolla erişilebilir __subclasses__()
; bu nedenle, tüm sınıfları bir eklenti dizininden importlib.import_module()
yüklerseniz ve temel sınıfın alt sınıflarına girerseniz, bunlara doğrudan erişebilirsiniz __subclasses__()
ve arabirim sözleşmesinin tümü için uygulandığından emin olabilirsiniz. onları örnekleme sırasında.
AccountingSystem
Yukarıdaki örnek için eklenti yükleme uygulaması şöyledir:
...
from importlib import import_module
class AccountingSystem(ABC):
...
_instance = None
@classmethod
def instance(cls):
if not cls._instance:
module_name = settings.ACCOUNTING_SYSTEM_MODULE_NAME
import_module(module_name)
subclasses = cls.__subclasses__()
if len(subclasses) > 1:
raise InvalidAccountingSystemError('More than one '
f'accounting module: {subclasses}')
if not subclasses or module_name not in str(subclasses[0]):
raise InvalidAccountingSystemError('Accounting module '
f'{module_name} does not exist or does not '
'subclass AccountingSystem')
cls._instance = subclasses[0]()
return cls._instance
Daha sonra muhasebe sistemi eklentisi nesnesine AccountingSystem
sınıf üzerinden erişebilirsiniz :
>>> accountingsystem = AccountingSystem.instance()
( Bu PyMOTW-3 yayınından esinlenilmiştir .)