एक- आधारित बेस क्लास विधि की बाल पद्धति के raise NotImplementedError()
अंदर भी कर सकता है @abstractmethod
।
माप मॉड्यूल (भौतिक उपकरणों) के एक परिवार के लिए एक नियंत्रण स्क्रिप्ट लिखने की कल्पना करें। प्रत्येक मॉड्यूल की कार्यक्षमता को संकीर्ण रूप से परिभाषित किया गया है, जो केवल एक समर्पित फ़ंक्शन को कार्यान्वित कर रहा है: एक रिले का एक सरणी हो सकता है, दूसरा मल्टी-चैनल डीएसी या एडीसी, दूसरा एक एमीटर।
उपयोग में आने वाले निम्न-स्तरीय कमांडों में से अधिकांश को उनके आईडी नंबर पढ़ने या उन्हें कमांड भेजने के लिए उदाहरण के लिए मॉड्यूल के बीच साझा किया जाएगा। आइए देखें कि हमारे पास इस बिंदु पर क्या है:
बेस क्लास
from abc import ABC, abstractmethod
class Generic(ABC):
''' Base class for all measurement modules. '''
def __init__(self):
def _read_ID(self):
def _send_command(self, value):
क्रियाओं को साझा किया
तब हमें पता चलता है कि मॉड्यूल-विशिष्ट कमांड क्रियाओं में से अधिकांश और इसलिए, उनके इंटरफेस का तर्क भी साझा किया जाता है। यहां 3 अलग-अलग क्रियाएं हैं, जिनके अर्थ लक्ष्य मॉड्यूल की एक संख्या पर विचार करते हुए आत्म-व्याख्यात्मक होंगे।
get(channel)
रिले: रिले की ऑन / ऑफ स्थिति प्राप्त करेंchannel
डीएसी: प्राप्त उत्पादन पर वोल्टेजchannel
एडीसी: इनपुट वोल्टेज प्राप्त करेंchannel
enable(channel)
रिले: रिले के उपयोग को सक्षम करेंchannel
DAC: आउटपुट चैनल के उपयोग को सक्षम करेंchannel
एडीसी: इनपुट चैनल के उपयोग को सक्षम करेंchannel
set(channel)
रिले: रिले को channel
चालू / बंद सेट करें
DAC: आउटपुट वोल्टेज को ऑन पर सेट करेंchannel
एडीसी: हम्म ... कुछ भी तार्किक दिमाग में नहीं आता है।
साझा क्रिया-कलापों को लागू किया गया
मेरा तर्क है कि उपरोक्त क्रियाओं को मॉड्यूल में साझा करने के लिए एक मजबूत मामला है क्योंकि हमने देखा कि उनका अर्थ उनमें से प्रत्येक के लिए स्पष्ट है। मैं अपना बेस क्लास लिखना जारी रखूँगा Generic
:
class Generic(ABC):
@abstractmethod
def get(self, channel):
pass
@abstractmethod
def enable(self, channel):
pass
@abstractmethod
def set(self, channel):
pass
उपवर्गों
अब हम जानते हैं कि हमारे उपवर्गों को इन विधियों को परिभाषित करना होगा। आइए देखें कि यह एडीसी मॉड्यूल के लिए कैसा दिख सकता है:
class ADC(Generic):
def __init__(self):
super().__init__()
def get(self, channel):
def enable(self, channel):
अब आप सोच रहे होंगे:
लेकिन यह एडीसी मॉड्यूल के लिए काम नहीं करेगा क्योंकि इसका set
कोई मतलब नहीं है क्योंकि हमने इसे ऊपर देखा है!
आप सही हैं: लागू set
नहीं करना एक विकल्प नहीं है क्योंकि जब आप अपने एडीसी ऑब्जेक्ट को तुरंत हटाने की कोशिश करते हैं तो पायथन नीचे त्रुटि करेगा।
TypeError: Can't instantiate abstract class 'ADC' with abstract methods 'set'
तो आपको कुछ लागू करना होगा, क्योंकि हमने set
एक लागू क्रिया (उर्फ '@abbridmethod') की है, जिसे दो अन्य मॉड्यूल द्वारा साझा किया गया है, लेकिन साथ ही, आपको कुछ भी लागू नहीं करना चाहिए
set
क्योंकि इस विशेष मॉड्यूल के लिए कोई मतलब नहीं है।
बचाव के लिए NotImplementedError
एडीसी वर्ग को इस तरह पूरा करके:
class ADC(Generic):
def set(self, channel):
raise NotImplementedError("Can't use 'set' on an ADC!")
आप एक साथ तीन बहुत अच्छी चीजें कर रहे हैं:
- आप किसी उपयोगकर्ता को गलत तरीके से एक कमांड ('सेट') जारी करने से बचा रहे हैं जो इस मॉड्यूल के लिए लागू नहीं है (और नहीं!)।
- आप उन्हें स्पष्ट रूप से बता रहे हैं कि समस्या क्या है (यह क्यों महत्वपूर्ण है इसके लिए 'बेयर अपवाद' के बारे में टेम्पोरलवुल्फ़ लिंक देखें)
- आप उन सभी अन्य मॉड्यूल के कार्यान्वयन की रक्षा कर रहे हैं जिनके लिए लागू किए गए क्रियाओं का
अर्थ है। यानी आप यह सुनिश्चित करें कि उन मॉड्यूल जिसके लिए इन क्रियाओं करना मेकअप भावना इन तरीकों को लागू करेगा और उस वे बिल्कुल इन क्रियाओं का उपयोग करके ऐसा करेंगे और न किसी और तदर्थ नाम।