अमूर्त आधार वर्गों के साथ इंटरफेस को लागू करना आधुनिक पायथन 3 में बहुत सरल है और वे प्लग-इन एक्सटेंशन के लिए एक इंटरफ़ेस अनुबंध के रूप में एक उद्देश्य की सेवा करते हैं।
इंटरफ़ेस / सार आधार वर्ग बनाएँ:
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)
एक सामान्य उपवर्ग बनाएँ और सभी अमूर्त विधियों को ओवरराइड करें:
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)
आप वैकल्पिक रूप से अमूर्त तरीकों में आम कार्यान्वयन कर सकते हैं create_sale_invoice()
, जैसा कि super()
स्पष्ट रूप से उपरोक्त उपवर्ग में है।
एक उपवर्ग की तात्कालिकता जो सभी अमूर्त विधियों को लागू नहीं करती है:
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
आप के साथ संबंधित एनोटेशन के संयोजन द्वारा अमूर्त गुण, स्थिर और वर्ग विधियां भी हो सकती हैं @abstractmethod
।
प्लगइन आधारित प्रणालियों को लागू करने के लिए सार बेस कक्षाएं बहुत अच्छी हैं। किसी वर्ग के सभी आयातित उपवर्गों के माध्यम से पहुँचा जा सकता है __subclasses__()
, इसलिए यदि आप एक प्लगइन निर्देशिका से सभी वर्गों को लोड करते हैं importlib.import_module()
और यदि वे आधार वर्ग को उप-वर्ग में रखते हैं, तो आपके पास उनके माध्यम से सीधे पहुंच है __subclasses__()
और आप सुनिश्चित कर सकते हैं कि इंटरफ़ेस अनुबंध सभी के लिए लागू है तात्कालिकता के दौरान उन्हें।
यहाँ AccountingSystem
ऊपर उदाहरण के लिए प्लगइन लोडिंग कार्यान्वयन है:
...
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
तब आप AccountingSystem
क्लास के माध्यम से अकाउंटिंग सिस्टम प्लगइन ऑब्जेक्ट को एक्सेस कर सकते हैं :
>>> accountingsystem = AccountingSystem.instance()
( इस PyMOTW-3 पोस्ट से प्रेरित )