दिलचस्प पोस्ट
didReiveiveRemoteNotification नहीं कहा जाता है, आईओएस 10 MongoDB रिश्तों: एम्बेड या संदर्भ? jQuery AJAX वर्ण एन्कोडिंग ASP.NET MVC रूट के लिए अनंत URL पैरामीटर जीसीएम पर पंजीकरण करते समय नल डिवाइस आईडी हो रही है मैं कैसे जाँच कर सकता हूँ कि अनुरोध AJAX के माध्यम से CodeIgniter में किया जाता है? मैं जावास्क्रिप्ट फ़ाइल को एक और जावास्क्रिप्ट फ़ाइल में कैसे शामिल कर सकता हूं? मैं gdb में एक लंबी स्ट्रिंग का पूरा मान कैसे मुद्रित करूं? Google Autocomplete परिणामों को केवल शहर और देश तक सीमित कैसे करें गैर-मानक मूल्यांकन (एनएसई) में dplyr के फिल्टर_ और MySQL से डेटा खींच रहा है जब तक सभी ईएस 6 वादे पूरा नहीं होते, तब तक इंतजार करें, वादे भी अस्वीकार कर दिए गए ^, $ Regex में इस प्रतीक का उपयोग कब किया जाए? सी # में WebBrowser नियंत्रण DocumentCompleted ईवेंट का उपयोग कैसे करें? संबंधित पथ और / या फ़ाइल नाम से पूर्ण पथ को हल करें उद्देश्य-सी ऑब्जेक्ट के लिए सूची चयनकर्ता

पायथन में सार बेस क्लासेस का उपयोग क्यों करें?

पायथन में बतख की टाइपिंग के पुराने तरीकों के लिए इस्तेमाल होने के नाते, मैं एबीसी (सार बेस क्लास) की आवश्यकता को समझने में विफल रहा। उनकी मदद का उपयोग करना अच्छा है।

मैंने पीईपी में तर्क को पढ़ने की कोशिश की, लेकिन यह मेरे सिर पर चला गया। अगर मैं एक अस्थायी अनुक्रम कंटेनर की तलाश कर रहा था, तो मैं __setitem__ लिए जांच __setitem__ , या इसे इस्तेमाल करने की अधिक संभावना ( ईएएफपी )। मैं संख्या मॉड्यूल के लिए वास्तविक जीवन उपयोग में नहीं आया हूं, जो एबीसी का उपयोग करता है, लेकिन यह सबसे निकटतम मुझे समझना है।

क्या कोई मुझे तर्क बता सकता है, कृपया?

वेब के समाधान से एकत्रित समाधान "पायथन में सार बेस क्लासेस का उपयोग क्यों करें?"

लघु संस्करण

एबीसी ग्राहकों और कार्यान्वित कक्षाओं के बीच एक उच्च स्तर के सिमेंटिक अनुबंध की पेशकश करते हैं।

दीर्घ संस्करण

एक वर्ग और इसके कॉलर के बीच एक अनुबंध है। वर्ग कुछ चीज़ों को करने और कुछ गुणों के लिए वादा करता है

अनुबंध के विभिन्न स्तर हैं

बहुत कम स्तर पर, अनुबंध में किसी विधि का नाम या इसके पैरामीटर की संख्या शामिल हो सकती है

एक स्थिर-टाइप की गई भाषा में, उस अनुबंध को संकलक द्वारा वास्तव में लागू किया जाएगा। अजगर में, आप यह पुष्टि करने के लिए ईएएफपी या आत्मनिरीक्षण का उपयोग कर सकते हैं कि अज्ञात ऑब्जेक्ट इस अपेक्षित अनुबंध को पूरा करता है।

लेकिन अनुबंध में उच्च-स्तरीय, अर्थ वादे भी हैं।

उदाहरण के लिए, यदि कोई __str__() विधि है, तो वस्तु की स्ट्रिंग प्रतिनिधित्व को वापस करने की उम्मीद है। यह ऑब्जेक्ट की सभी सामग्रियों को हटा सकता है , ट्रांजैक्शन ले सकता है और प्रिंटर के बाहर रिक्त पृष्ठ थूक सकता है … लेकिन अजगर मैनुअल में बताए गए कार्यों की एक सामान्य समझ है।

यह एक विशेष मामला है, जहां सिमेंटिक अनुबंध मैनुअल में वर्णित है। print() विधि को क्या करना चाहिए? क्या यह ऑब्जेक्ट को एक प्रिंटर या एक लाइन के लिए स्क्रीन पर या कुछ और लिखना चाहिए? यह निर्भर करता है – आपको यहां पूर्ण अनुबंध को समझने के लिए टिप्पणियां पढ़ने की आवश्यकता है। क्लाइंट कोड का एक टुकड़ा जो जांचता है कि print() पद्धति में मौजूद अनुबंध के भाग की पुष्टि हुई है – कि एक विधि कॉल किया जा सकता है, लेकिन यह नहीं कि कॉल के उच्च स्तरीय शब्दों पर सहमति है

एक सार बेस कक्षा (एबीसी) को परिभाषित करना, कक्षा कार्यान्वयनकर्ताओं और कॉल करने वालों के बीच एक अनुबंध का निर्माण करने का एक तरीका है। यह केवल विधि नामों की सूची नहीं है, लेकिन उन विधियों को क्या करना चाहिए, यह एक साझा समझ है। यदि आप इस एबीसी से प्राप्त करते हैं, तो आप print() विधि की शब्दावली सहित टिप्पणियों में वर्णित सभी नियमों का पालन करने का वादा कर रहे हैं।

पायथन की बतख-टाइपिंग में स्थिर-टाइपिंग पर लचीलेपन में कई फायदे हैं, लेकिन यह सभी समस्याओं का समाधान नहीं करता है एबीसी पायथन के फ्री-फॉर्म और स्थिर-टाइप किए गए भाषा के बंधन-और-अनुशासन के बीच एक मध्यवर्ती समाधान प्रदान करते हैं।

@ ओडथिंकिंग का जवाब गलत नहीं है, लेकिन मुझे लगता है कि यह वास्तविक , व्यावहारिक कारण को याद करता है, अजगर के पास बतख-टाइपिंग की दुनिया में एबीसी है

सार विधियां साफ-सुथरी हैं, लेकिन मेरी राय में वे बतख टाइपिंग द्वारा पहले से ही कवर नहीं किए गए उपयोग के मामलों को वास्तव में नहीं भरते हैं। सार बेस क्लास 'असली शक्ति जिस तरह से आप isinstance और issubclass के व्यवहार को अनुकूलित करने की अनुमति में निहित है। ( __subclasshook__ मूल रूप से पायथन की __instancecheck__ और __subclasscheck__ हुक के शीर्ष पर मित्रवत API है।) कस्टम प्रकारों पर काम करने के लिए अंतर्निर्मित निर्माणों का अनुकूलन पायथन के दर्शन का बहुत हिस्सा है।

पायथन का स्रोत कोड अनुकरणीय है। यहां बताया गया है कि collections.Container को मानक पुस्तकालय (लिखित के समय) में परिभाषित किया गया है:

 class Container(metaclass=ABCMeta): __slots__ = () @abstractmethod def __contains__(self, x): return False @classmethod def __subclasshook__(cls, C): if cls is Container: if any("__contains__" in B.__dict__ for B in C.__mro__): return True return NotImplemented 

__subclasshook__ की यह परिभाषा कहती है कि __contains__ विशेषता वाले किसी भी वर्ग को कंटेनर का एक उप-वर्ग माना जाता है, भले ही वह सीधे इसे उप-वर्ग न हो तो मैं यह लिख सकता हूँ:

 class ContainAllTheThings(object): def __contains__(self, item): return True >>> issubclass(ContainAllTheThings, collections.Container) True >>> isinstance(ContainAllTheThings(), collections.Container) True 

दूसरे शब्दों में, यदि आप सही इंटरफ़ेस को लागू करते हैं , तो आप एक उप-वर्ग हैं! एबीसी पिथान में इंटरफेस को परिभाषित करने का एक औपचारिक तरीका प्रदान करते हैं, जबकि बतख-टाइपिंग की भावना को सही रखते हुए। इसके अलावा, यह एक ऐसे तरीके से काम करता है जो ओपन-क्लोजेड सिद्धांत का सम्मान करता है।

पायथन का ऑब्जेक्ट मॉडल अधिकाधिक एक "पारंपरिक" ओओ सिस्टम (जिसके द्वारा मेरा मतलब जावा *) के समान दिखता है – हमें येर कक्षाएं मिलती हैं, yer ऑब्जेक्ट्स, yer विधियां – परन्तु जब आप सतह को खरोंचते हैं तो आपको कुछ और अधिक मिल जाएगा और अधिक लचीला। इसी तरह, अमूर्त आधार वर्गों का पायथन का विचार जावा डेवलपर के लिए पहचाना जा सकता है, लेकिन व्यवहार में वे बहुत अलग उद्देश्य के लिए अभिप्रेत हैं।

मैं कभी-कभी खुद को बहुविध कार्यों को लिखता हूं जो एक आइटम या वस्तुओं का एक संग्रह पर कार्य कर सकते हैं, और मुझे isinstance(x, collections.Iterable) hasattr(x, '__iter__') जो hasattr(x, '__iter__') या समकक्ष try...except से ज्यादा पढ़ने योग्य है try...except ब्लॉक को try...except । (यदि आपको पायथन नहीं पता था, तो उन तीनों में से कौन से कोड को स्पष्ट किया जाएगा?)

मुझे लगता है कि मुझे शायद ही कभी अपना एबीसी लिखना पड़ता है – मैं बतख टंकण पर भरोसा करना पसंद करता हूं – और मैं आमतौर पर रिफैक्टरिंग के माध्यम से एक की आवश्यकता की खोज करता हूं। अगर मुझे एक बहुरूपभूत कार्य मिल रहा है, जो बहुत सारे विशेषता जांच करता है, या बहुत सारी फ़ंक्शंस एक ही विशेषता जांच कर रही है, तो गंध निकाले जाने के इंतजार में एबीसी के अस्तित्व का सुझाव देता है।

* क्या जावा एक "पारंपरिक" ओओ सिस्टम है, इसके बावजूद बहस में नहीं आ रहा है …


परिशिष्ट : हालांकि एक सार बेस क्लास isinstance और issubclass के व्यवहार को ओवरराइड कर सकता है, यह अभी भी आभासी उप-वर्ग के एमआरओ दर्ज नहीं करता है। यह ग्राहकों के लिए एक संभावित isinstance(x, MyABC) == True : हर ऑब्जेक्ट जिसके लिए isinstance(x, MyABC) == True में MyABC पर परिभाषित विधियां हैं

 class MyABC(metaclass=abc.ABCMeta): def abc_method(self): pass @classmethod def __subclasshook__(cls, C): return True class C(object): pass # typical client code c = C() if isinstance(c, MyABC): # will be true c.abc_method() # raises AttributeError 

दुर्भाग्य से, इनमें से कोई एक "बस ऐसा नहीं करता है" जाल (जिनमें से पायथन अपेक्षाकृत कम है!): एबीसी को __subclasshook__ और गैर-अमूर्त तरीकों दोनों के साथ परिभाषित करने से बचें। इसके अलावा, आपको __subclasshook__ की अपनी परिभाषा को अपने एबीसी परिभाषित करने के सार तत्वों के सेट के अनुरूप बनाना चाहिए।

एबीसी की एक आसान विशेषता यह है कि यदि आप सभी आवश्यक तरीकों (और गुण) को लागू नहीं करते हैं, तो आपको एक AttributeError एरर की बजाय तत्काल पर त्रुटि मिलती है, संभवतः बहुत बाद में, जब आप वास्तव में अनुपलब्ध विधि का उपयोग करने की कोशिश करते हैं

 from abc import ABCMeta, abstractmethod class Base(object): __metaclass__ = ABCMeta @abstractmethod def foo(self): pass @abstractmethod def bar(self): pass class Concrete(Base): def foo(self): pass # We forget to declare `bar` c = Concrete() # TypeError: "Can't instantiate abstract class Concrete with abstract methods bar" 

उदाहरण से https://dbader.org/blog/abstract-base-classes-in-python

यह यह निर्धारित करेगा कि कोई प्रोटोकॉल प्रोटोकॉल में सभी तरीकों की उपस्थिति की जांच करने के बिना या गैर-समर्थन के कारण "दुश्मन" क्षेत्र में एक अपवाद को ट्रिगर किए बिना दिए गए प्रोटोकॉल का समर्थन करता है या नहीं।