वैचारिक रूप से, एक वर्ग मौजूद है परिभाषित करने के लिए क्या वस्तुओं का एक सेट (के उदाहरण कक्षा) आम है। बस इतना ही। यह कक्षा द्वारा परिभाषित साझा पैटर्न के अनुसार कक्षा के उदाहरणों के बारे में सोचने की अनुमति देता है। यदि हर वस्तु अलग थी, तो हम कक्षाओं का उपयोग करने से परेशान नहीं होंगे, हम सिर्फ शब्दकोशों का उपयोग करेंगे।
एक मेटाक्लास एक साधारण वर्ग है, और यह उसी कारण से मौजूद है; परिभाषित करने के लिए कि इसके उदाहरणों के लिए आम क्या है।
- एक उदाहरण पर गुण देखने उदाहरण अपने वर्ग के द्वारा पीछा किया, के सभी सुपर-क्लास के बाद की जाँच करता है: डिफ़ॉल्ट metaclass
type
जैसे सब सामान्य नियमों कि कक्षाएं बनाने के लिए और उदाहरणों जिस तरह से आप के लिए इस्तेमाल कर रहे हैं काम करते हैं, प्रदान करता है एमआरओ आदेश
- कॉलिंग
MyClass(*args, **kwargs)
एक उदाहरण पाने के लिए i = MyClass.__new__(MyClass, *args, **kwargs)
invokes, तो i.__init__(*args, **kwargs)
invokes यह
- एक वर्ग वर्ग
की विशेषताओं में सभी के नाम वर्ग ब्लॉक में बाध्य करके एक वर्ग ब्लॉक में परिभाषाओं से बनाई गई है आरंभ करने के लिए
- आदि
आप कुछ कक्षाएं कि सामान्य वर्गों के लिए अलग तरह से काम करना चाहते हैं, तो आप एक metaclass को परिभाषित करने और अपने असामान्य वर्गों type
बजाय metaclass के उदाहरण बना सकते हैं। आपका मेटाक्लास लगभग निश्चित रूप से type
का उप-वर्ग होगा, क्योंकि शायद आप अपनी अलग-अलग प्रकार की कक्षा पूरी तरह से अलग नहीं करना चाहते हैं; जैसे कि आप पुस्तकों के कुछ उप-समूह को थोड़ा अलग तरीके से व्यवहार करना चाहते हैं (कहें, किताबें जो अन्य कार्यों के संकलन हैं) और पूरी तरह से अलग वर्ग की बजाय Book
के उप-वर्ग का उपयोग करें।
यदि आप कुछ वर्गों को सामान्य कक्षाओं में अलग-अलग काम करने का तरीका परिभाषित करने की कोशिश नहीं कर रहे हैं, तो मेटाक्लास शायद सबसे उपयुक्त समाधान नहीं है। ध्यान दें कि "वर्ग परिभाषित करते हैं कि उनके उदाहरण कैसे काम करते हैं" पहले से ही एक बहुत ही लचीला और अमूर्त प्रतिमान है; अधिकांश समय आपको कक्षाओं के काम को बदलने की जरूरत नहीं है।
यदि आप चारों ओर Google हैं, तो आप मेटाक्लास के कई उदाहरण देखेंगे जो वास्तव में कक्षा निर्माण के आसपास सामानों का एक गुच्छा करने के लिए उपयोग किए जा रहे हैं; अक्सर कक्षा विशेषताओं को स्वचालित रूप से संसाधित करते हैं, या स्वचालित रूप से कहीं से नए खोजते हैं। मैं वास्तव में मेटाक्लास के उन महान उपयोगों को नहीं बुलाऊंगा। वे कक्षाओं के काम को बदलने में नहीं बदल रहे हैं, वे बस कुछ कक्षाओं को संसाधित कर रहे हैं। कक्षा बनाने के लिए एक फैक्ट्री फ़ंक्शन, या कक्षा निर्माण के बाद तुरंत आप जिस कक्षा विधि का आह्वान करते हैं, या सभी वर्ग सजावट के सर्वश्रेष्ठ, मेरी राय में इस तरह की चीज को लागू करने का एक बेहतर तरीका होगा।
लेकिन कभी-कभी आप कक्षाओं के पाइथन के डिफ़ॉल्ट व्यवहार को कुछ अवधारणात्मक सरल करने के लिए जटिल कोड लिखते हैं, और यह वास्तव में मेटाक्लास स्तर पर "आगे निकलने" और इसे लागू करने में मदद करता है।
एक काफी मामूली उदाहरण "सिंगलटन पैटर्न" है, जहां आपके पास एक वर्ग है जिसमें केवल एक उदाहरण हो सकता है; क्लास को कॉल करना एक मौजूदा इंस्टेंस लौटाएगा यदि कोई पहले ही बनाया जा चुका है। व्यक्तिगत रूप से मैं सिंगलेट के खिलाफ हूं और उनके उपयोग की सलाह नहीं दूंगा (मुझे लगता है कि वे केवल वैश्विक चर हैं, जो कि नव निर्मित उदाहरणों की तरह दिखने के लिए चालाकी से छिपे हुए हैं ताकि सूक्ष्म बग का कारण बनने की संभावना अधिक हो)। लेकिन लोग उनका उपयोग करते हैं, और __new__
और __init__
का उपयोग करके सिंगलटन कक्षाएं बनाने के लिए बड़ी संख्या में व्यंजन हैं। इस तरह से ऐसा करना थोड़ा परेशान हो सकता है, मुख्य रूप से क्योंकि पाइथन __new__
पर कॉल करना चाहता है और उसके परिणामस्वरूप __init__
पर कॉल करना चाहता है, इसलिए आपको हर बार जब कोई व्यक्ति किसी तक पहुंच का अनुरोध करता है तो अपना प्रारंभिक कोड फिर से चलाने का तरीका नहीं ढूंढना होगा सिंगलटन। लेकिन आसान नहीं होगा अगर हम पाइथन को सीधे बता सकें कि जब हम क्लास को कॉल करना चाहते हैं, तो चीजों को स्थापित करने की कोशिश करने के बजाए हम क्या करना चाहते हैं ताकि वे ऐसा करना चाहते हैं जो हम अंत में चाहते हैं?
class Singleton(type):
def __init__(self, *args, **kwargs):
super(Singleton, self).__init__(*args, **kwargs)
self.__instance = None
def __call__(self, *args, **kwargs):
if self.__instance is None:
self.__instance = super(Singleton, self).__call__(*args, **kwargs)
return self.__instance
10 लाइनों के तहत, और यह बस __metaclass__ = Singleton
जोड़कर एकमात्र में सामान्य वर्गों बदल जाता है, अर्थात कुछ भी नहीं एक घोषणा है कि वे एक सिंगलटन हैं और अधिक से अधिक। कक्षा स्तर पर कुछ भी हैक करने के बजाय, इस स्तर पर इस तरह की चीज को लागू करने के लिए यह आसान है।
लेकिन आपके विशिष्ट Book
कक्षा के लिए, ऐसा लगता है कि आपको मेटाक्लास द्वारा सहायता की जाने वाली किसी भी चीज़ को करने की आवश्यकता नहीं है। आपको वास्तव में मेटाक्लास के लिए पहुंचने की आवश्यकता नहीं है जब तक आपको सामान्य नियम मिलते हैं कि कक्षाओं के काम से आपको कुछ ऐसा करने से रोका जा रहा है जो सरल तरीके से सरल होना चाहिए (जो अलग-अलग "आदमी से, मेरी इच्छा है कि मैंने नहीं किया इन सभी वर्गों के लिए इतना टाइप करना होगा, मुझे आश्चर्य है कि क्या मैं सामान्य बिट्स को स्वतः उत्पन्न कर सकता हूं? ")। असल में, मैंने वास्तव में काम पर पाइथन का उपयोग करने के बावजूद कुछ वास्तविक के लिए मेटाक्लास का उपयोग नहीं किया है; मेरे सभी मेटाक्लासेस खिलौने उदाहरण हैं जैसे उपरोक्त Singleton
या अन्यथा मूर्खतापूर्ण अन्वेषण।
मेटाक्लास के पहले नियम: यदि आपको * पता नहीं है कि आपको मेटाक्लास की आवश्यकता है, तो आपको * मेटाक्लास की आवश्यकता नहीं है। –