2012-04-28 16 views
5

मैं इस माध्यम से गुजर चुका हूं: What is a metaclass in Python?पायथन में, मुझे मेटा क्लास का उपयोग कब करना चाहिए?

लेकिन क्या कोई भी विशेष रूप से मेटा क्लास अवधारणा का उपयोग कब करना चाहिए और जब यह बहुत आसान हो?

मान लीजिए मैं नीचे की तरह एक वर्ग है:

class Book(object): 
    CATEGORIES = ['programming','literature','physics'] 
    def _get_book_name(self,book): 
     return book['title'] 
    def _get_category(self, book): 
     for cat in self.CATEGORIES: 
      if book['title'].find(cat) > -1: 
       return cat 
     return "Other" 


if __name__ == '__main__': 
    b = Book() 
    dummy_book = {'title':'Python Guide of Programming', 'status':'available'} 
    print b._get_category(dummy_book) 

इस वर्ग के लिए।

मुझे किस स्थिति में मेटा क्लास का उपयोग करना चाहिए और यह क्यों उपयोगी है?

अग्रिम धन्यवाद।

+12

मेटाक्लास के पहले नियम: यदि आपको * पता नहीं है कि आपको मेटाक्लास की आवश्यकता है, तो आपको * मेटाक्लास की आवश्यकता नहीं है। –

उत्तर

-1

मेटा क्लास का उपयोग कैसे करें और कब उपयोग करें, यह जानने के लिए Meta Class Made Easy लिंक देखें।

8

जब आप कक्षा को बनाए जा रहे हैं तो आप मेटाक्लास का उपयोग करते हैं। मेटाक्लास को शायद ही कभी आवश्यकता होती है, उन्हें डीबग करना मुश्किल होता है, और उन्हें समझना मुश्किल होता है - लेकिन कभी-कभी वे ढांचे को उपयोग करने में आसान बना सकते हैं। हमारे 600 क्लोक कोड बेस में हमने मेटाक्लास को 7 बार उपयोग किया है: एबीसीएमटा एक बार, 4 एक्स मॉडल। डैंजो से सबफील्डबेस, और दो बार मेटाक्लास जो कक्षाओं को Django में विचारों के रूप में उपयोग करने योग्य बनाता है। @Ignacio लिखते हैं, यदि आप जानते हैं कि आपको मेटाक्लास (और अन्य सभी विकल्पों पर विचार किया गया है) की आवश्यकता है, तो को मेटाक्लास की आवश्यकता नहीं है।

+5

और यहां तक ​​कि यदि आप कक्षा को बदलना चाहते हैं, तो एक वर्ग सजावट अक्सर सरल और शक्तिशाली के रूप में होता है। केवल सबसे उन्नत कुशलताएं वास्तव में मेटाक्लास से लाभान्वित होती हैं। – delnan

1

जो भी कारण Class[x], x in Class आदि जैसे सामान करना चाहता हूँ के लिए आप, आप metaclasses उपयोग करने के लिए है, तो:

class Meta(type): 
    def __getitem__(cls, x): 
     return x ** 2 

    def __contains__(cls, x): 
     return int(x ** (0.5)) == x ** 0.5 

# Python 2.x 
class Class(object): 
    __metaclass__ = Meta 

# Python 3.x 
class Class(metaclass=Meta): 
    pass 

print Class[2] 
print 4 in Class 
+3

* चाहते हैं * लेकिन क्या यह करने के लिए सबसे अच्छी बात है? शायद ही कभी, अगर कभी। मैं किसी भी समय ऐसा नहीं सोच सकता जब मैं इस तरह की चीजें करना चाहता था, लेकिन अगर मेरे पास भी था, तो यह दृढ़ता से मुझे सुझाव देगा कि मैं इसे गलत तरीके से कर रहा हूं। –

3

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

एक मेटाक्लास एक साधारण वर्ग है, और यह उसी कारण से मौजूद है; परिभाषित करने के लिए कि इसके उदाहरणों के लिए आम क्या है।

  • एक उदाहरण पर गुण देखने उदाहरण अपने वर्ग के द्वारा पीछा किया, के सभी सुपर-क्लास के बाद की जाँच करता है: डिफ़ॉल्ट 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 या अन्यथा मूर्खतापूर्ण अन्वेषण।

3

जब भी आपको अपनी रचना सहित कक्षाओं के लिए डिफ़ॉल्ट व्यवहार को ओवरराइड करने की आवश्यकता होती है तो मेटाक्लास का उपयोग किया जाता है।

एक वर्ग नाम से बनाया जाता है, ठिकानों की एक टपल, और एक वर्ग dict। आप किसी भी इनपुट में परिवर्तन करने के लिए निर्माण प्रक्रिया को रोक सकते हैं।

तुम भी वर्गों द्वारा उपलब्ध कराई गई सेवाओं के किसी भी ओवरराइड कर सकते हैं:

  • __call__ जो उदाहरण बना करने के लिए प्रयोग किया जाता है
  • __getattribute__ जो एक वर्ग
  • __setattr__ जो नियंत्रित करता है पर गुण और तरीकों देखने के लिए प्रयोग किया जाता है सेटिंग विशेषताओं
  • __repr__ जो कैसे वर्ग diplayed नियंत्रित

संक्षेप में, मेटाक्लास का उपयोग तब किया जाता है जब आपको नियंत्रित करने की आवश्यकता होती है कि कक्षाएं कैसे बनाई जाती हैं या जब आपको कक्षाओं द्वारा प्रदान की जाने वाली किसी भी सेवा को बदलने की आवश्यकता होती है।

संबंधित मुद्दे