2009-01-24 14 views
14

मैंने हाल ही में अजगर में मेटाक्लास की खोज की है।क्या कोई पाइथन/अन्य भाषाओं में मेटा-मेटा-क्लासेस/मेटा-मेटा-मेटा-क्लासेस का उपयोग कर रहा है?

मूल रूप से पायथन में एक मेटाक्लास एक वर्ग है जो कक्षा बनाता है। कई उपयोगी कारण हैं कि आप ऐसा क्यों करना चाहते हैं - उदाहरण के लिए किसी भी प्रकार की कक्षा प्रारंभिकरण। कारखानों पर कक्षाओं को पंजीकृत करना, गुणों की जटिल मान्यता, विरासत कैसे काम करता है, इत्यादि बदलना आदि। यह सब न केवल संभव लेकिन सरल हो जाता है।

लेकिन पाइथन में, मेटाक्लास भी सादे वर्ग हैं। तो, मैं सोच अगर अमूर्त उपयोगी उच्च जा सकते हैं शुरू कर दिया है, और यह है कि यह कर सकते हैं और है कि मुझे लगता है:

  • एक metaclass से मेल खाती है या एक पैटर्न में एक भूमिका को लागू करता है (GOF पैटर्न भाषाओं के रूप में)।
  • एक मेटा-metaclass पैटर्न ही
  • (अगर हम इसे नहीं बल्कि सिर्फ एक वर्ग की तुलना में, सार भूमिकाओं का प्रतिनिधित्व वर्गों की tuples बनाने की अनुमति) है एक मेटा-मेटा-metaclass एक पैटर्न कारखाने, जो मेल खाती है जीओएफ पैटर्न समूह के लिए, उदाहरण के लिए रचनात्मक, संरचनात्मक, व्यवहारिक। एक कारखाना जहां आप किसी निश्चित प्रकार की समस्या के मामले का वर्णन कर सकते हैं और यह आपको कक्षाओं का एक सेट देगा जो इसे हल करता है।
  • मेटा-मेटा-मेटा-मेटाक्लास (जहां तक ​​मैं जा सकता हूं), पैटर्न फैक्टरी फैक्टरी है, एक कारखाना जिसमें आप शायद अपनी समस्या के प्रकार का वर्णन कर सकते हैं और यह आपको एक पैटर्न कारखाना देगा पूछना।

मुझे इस ऑनलाइन के बारे में कुछ सामान मिला है, लेकिन अधिकतर उपयोगी नहीं है। एक समस्या यह है कि विभिन्न भाषाएं मेटाक्लास को थोड़ा अलग तरीके से परिभाषित करती हैं।

क्या किसी और ने पाइथन/अन्य जगहों में मेटाक्लास का उपयोग किया है, या इसे जंगली में इस्तेमाल किया है, या इसके बारे में सोचा है? अन्य भाषाओं में अनुरूप क्या हैं? जैसे सी ++ में टेम्पलेट रिकर्सन कितना गहरा हो सकता है?

मैं इसे और अधिक शोध करना चाहता हूं।

+0

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

उत्तर

4

स्मॉलटॉक में कक्षा प्रणाली अध्ययन करने के लिए एक दिलचस्प है। स्मॉलटॉक में, सबकुछ एक वस्तु है और प्रत्येक ऑब्जेक्ट में एक वर्ग होता है। यह इस बात का तात्पर्य नहीं है कि पदानुक्रम अनंत तक जाता है। अगर मैं सही ढंग से याद है, यह हो जाता है की तरह कुछ:

5 -> पूर्णांक -> पूर्णांक वर्ग -> Metaclass -> Metaclass वर्ग -> Metaclass -> ... (यह लूप)

कहाँ '->' denotes "का एक उदाहरण है"।

+0

धन्यवाद, कुछ अन्य लोगों ने छोटे-छोटे लोगों का उल्लेख किया। मुझे मुझे वीएम स्क्वाक करना होगा और छोटे-छोटे के मेटाक्लास को पायथन के साथ तुलना करना होगा। –

7

अपने प्रश्न का उत्तर देने के लिए: नहीं।

इसे और अधिक शोध करने के लिए स्वतंत्र महसूस करें।

हालांकि, ध्यान दें कि आप कोड के साथ डिजाइन पैटर्न (जो सिर्फ विचार कर रहे हैं) सम्मिश्रण किया है (जो एक कार्यान्वयन है।)

अच्छा कोड अक्सर डिजाइन पैटर्न इंटरलॉकिंग की एक संख्या को दर्शाता है। इसे औपचारिक बनाने का कोई आसान तरीका नहीं है। सबसे अच्छा आप कर सकते हैं एक अच्छी तस्वीर, अच्छी तरह से लिखित डॉकस्ट्रिंग, और विधि नाम जो विभिन्न डिजाइन पैटर्न को प्रतिबिंबित करते हैं।

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


संपादित

"कक्षाएं बनाने metaclasses वास्तव में इतना मूर्ख कैसे उनकी उपयोगिता अचानक बाहर चलाने के लिए करता है?"

कक्षा बनाने वाला एक वर्ग ठीक है।तो इतना ही है। तथ्य यह है कि लक्ष्य वर्ग एक मेटा वर्ग या एक अमूर्त सुपरक्लास या एक ठोस वर्ग है, इससे कोई फर्क नहीं पड़ता। मेटाक्लास वर्ग बनाते हैं। वे अन्य मेटाक्लास बना सकते हैं, जो अजीब है, लेकिन वे अभी भी वर्ग बनाने वाले मेटाक्लास हैं।

उपयोगिता "अचानक" समाप्त हो जाती है क्योंकि मेटाक्लास में कोई वास्तविक चीज़ नहीं है (या यहां तक ​​कि लिख भी सकती है) जो एक और मेटाक्लास बनाता है। ऐसा नहीं है कि यह "अचानक" मूर्खतापूर्ण हो जाता है। यह है कि वहां कुछ भी उपयोगी नहीं है।

जैसा कि मैं बीज हूं, इसे शोधने में संकोच न करें। उदाहरण के लिए, वास्तव में एक मेटाक्लास लिखें जो एक और मेटाक्लास बनाता है। मज़े करो। वहां कुछ उपयोगी हो सकता है।

ओओ का बिंदु कक्षा परिभाषाओं को लिखना है जो असली दुनिया की इकाइयों को मॉडल करते हैं। इस प्रकार, कई मेटाब्लास कई संबंधित वर्गों के पार-काटने के पहलुओं को परिभाषित करने के लिए कभी-कभी आसान होता है। (यह कुछ पहलू-ओरिएंटेड प्रोग्रामिंग करने का एक तरीका है।) यह सब एक मेटाक्लास वास्तव में कर सकता है; यह कुछ कार्यों को पकड़ने के लिए एक जगह है, जैसे __new__(), जो कक्षा के उचित भाग नहीं हैं।

+0

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

+0

@ mike.amy: "कठिन" से मेरा मतलब समझ में नहीं आया। "थोड़ा चुनौतीपूर्ण" नहीं है। यह बहुत मुश्किल है - कभी-कभी असंभव - औपचारिकताओं में कई अच्छी तरह से विचार-विमर्श डिजाइन पैटर्न को विसर्जित करना। कुछ अच्छे डिजाइन निर्णय आदतें हैं और औपचारिकता के लिए कठिन हैं। कछुए के लिए –

18

यह मुझे अनन्त खोज की याद दिलाता है कि कुछ लोग "पैटर्न के सामान्य कार्यान्वयन" को बनाने के लिए प्रतीत होते हैं। एक कारखाने की तरह जो कोई ऑब्जेक्ट (including another factory), या एक सामान्य उद्देश्य निर्भरता इंजेक्शन ढांचा बना सकता है जो वास्तव में कुछ कोड लिखने से प्रबंधित करने के लिए कहीं अधिक जटिल है।

जब मैं ज़ेंड फ्रेमवर्क प्रोजेक्ट का प्रबंधन कर रहा था तो मुझे नाभि-दृश्य के बिंदु पर अमूर्तता के लोगों के इरादे से निपटना पड़ा। मैंने उन घटकों को बनाने के प्रस्तावों का एक गुच्छा बंद कर दिया जो कुछ भी नहीं करते थे, वे गोफ पैटर्न के जादुई कार्यान्वयन थे, हालांकि लक्ष्य एक लक्ष्य के साधन के बजाय स्वयं में एक लक्ष्य था।

अमूर्तता के लिए कम रिटर्न का एक बिंदु है। कुछ अमूर्तता बहुत बढ़िया है, लेकिन आखिर में आपको कोड लिखना होगा जो कुछ उपयोगी करता है।

अन्यथा यह केवल turtles all the way down है।

+1

+1! – Seth

+1

हमें डिस्कवर्ल्ड आर्किटेक्चरल पैटर्न –

+0

के साथ आने की आवश्यकता है, आप पोस्ट मुझे [वॉन न्यूमैन मशीन] (https://en.wikipedia.org/wiki/Monolith_ (Space_Odyssey)), मोनोलिथ्स उर्फ ​​से याद दिलाते हैं अंतरिक्ष ओडिसी श्रृंखला। –

6

2007 में प्रोग्रामिंग भाषा सम्मेलन के इतिहास के दौरान, साइमन पेटन जोन्स ने टिप्पणी की कि हास्केल टाइप क्लासेस का उपयोग करके मेटा प्रोग्रामिंग की अनुमति देता है, लेकिन यह वास्तव में सभी तरह से कछुए करता है। आप हास्केल में मेटा-मेटा-मेटा-मेटा इत्यादि प्रोग्राम कर सकते हैं, लेकिन उन्होंने कभी भी संकेत के 3 से अधिक स्तरों का उपयोग करके किसी के बारे में कभी नहीं सुना है।

गाय स्टील ने बताया कि लिस्प और योजना में यह वही बात है। आप बैकटिक्स का उपयोग करके मेटा-प्रोग्रामिंग कर सकते हैं और evals (आप एक पायथन लम्बाडा, थोड़े के रूप में बैकटिक के बारे में सोच सकते हैं), लेकिन उन्होंने कभी भी 3 से अधिक बैकटिक्स का उपयोग नहीं किया है।

संभवतः उन्होंने आपके पास या आपके पास से अधिक कोड देखा है, इसलिए यह कहना थोड़ा सा असाधारण है कि कोई भी मेटा के 3 स्तरों से आगे नहीं चला है।

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

+0

आप वास्तव में ऐसा महसूस करते हैं कि आप कुछ स्तरों तक पहुंचने की कोशिश कर पागल हो रहे हैं। आश्रय का उल्लेख करने के लिए +1। – Triptych

1

जब से मैंने पहली बार पाइथन में मेटाक्लास को समझ लिया, तो मैंने सोचा कि "मेटा-मेटा क्लास के साथ क्या किया जा सकता है?"। यह कम से कम 10 साल पहले है - और अब, कुछ महीने पहले, यह मेरे लिए स्पष्ट हो गया कि पाइथन कक्षा निर्माण में एक तंत्र है जिसमें वास्तव में "मेटा-मेटा" वर्ग शामिल है। और इसलिए, इसके लिए कुछ उपयोग की कल्पना करना संभव है।

अजगर में वस्तु इन्स्टेन्शियशन सारांश यह है: जब भी एक "बुला" एक ही एक साधारण समारोह, वर्ग के __new__ और __init__ फोन करने के लिए इस्तेमाल किया वाक्य रचना के साथ अपने वर्ग से अजगर में एक वस्तु को दर्शाता है। वर्ग पर इन विधियों की कॉलिंग "ऑर्केस्ट्रेट्स" वास्तव में कक्षा 'मेटाक्लास' __call__ विधि है। आम तौर पर जब कोई पाइथन में मेटाक्लास लिखता है, तो मेटाक्लास के __new__ या __init__ विधि को अनुकूलित किया जाता है।

तो, यह पता चला है कि एक "मेटा-मेटा" वर्ग लिख कर एक अपने __call__ विधि अनुकूलित कर सकते हैं और इस प्रकार को नियंत्रित जो पैरामीटर पारित कर रहे हैं और metaclass के __new__ और __init__ तरीकों के लिए, और के नाम से जाना है, तो कुछ अन्य कोड है उन के पहले से पहले। अंत में क्या पता चला है कि मेटाकल्स स्वयं आमतौर पर हार्डकोड होते हैं और किसी को भी बहुत बड़ी परियोजनाओं में, कुछ भी, यदि कोई हो, तो इसकी आवश्यकता होती है। इसलिए "मेटा मेटा" कॉल पर किए जा सकने वाले किसी भी अनुकूलन को आम तौर पर मेटाक्लास पर ही किया जाता है।

और उनको, पाइथन मेटाक्लास के लिए उन अन्य कम लगातार उपयोग होते हैं - कोई मेटाक्लास में __add__ विधि को कस्टमाइज़ कर सकता है ताकि वे परिभाषित कक्षाएं "addable" हों, और दो व्युत्पन्न वर्गों को सुपरक्लास के रूप में बनाए गए क्लास बनाएं । यह तंत्र पूरी तरह से मेटाक्लास के साथ भी मान्य है - इसलिए, इसलिए हमारे पास "कुछ वास्तविक कोड है", "मेटा-मेटा" वर्ग का एक उदाहरण है जो किसी को क्लास घोषणा पर जोड़कर कक्षा के लिए "मेटाक्लास" लिखने की अनुमति देता है :

class MM(type): 
    def __add__(cls, other): 
     metacls = cls.__class__ 
     return metacls(cls.__name__ + other.__name__, (cls, other), {}) 

class M1(type, metaclass=MM): 
    def __new__(metacls, name, bases, namespace): 
     namespace["M1"] = "here" 
     print("At M1 creation") 
     return super().__new__(metacls, name, bases, namespace) 

class M2(type, metaclass=MM): 
    def __new__(metacls, name, bases, namespace): 
     namespace["M2"] = "there" 
     print("At M2 creation") 
     return super().__new__(metacls, name, bases, namespace) 

और हम देख सकते हैं कि इंटरैक्टिव सांत्वना पर काम कर रहा: की अनुमति देकर

In [22]: class Base(metaclass = M1 + M2): 
    ...:  pass 
    ...: 
At M1 creation 
At M2 creation 

ध्यान दें कि अजगर में के रूप में विभिन्न metaclasses आमतौर पर गठबंधन करने के लिए मुश्किल हो जाता है, यह वास्तव में उपयोगी हो सकता है एक उपयोगकर्ता द्वारा निर्मित मेटाक्लास को लाइब्रेरी या स्टडलिब के साथ जोड़ा जाना चाहिए, इसके बिना इसे स्पष्ट रूप से पूर्व के माता-पिता के रूप में घोषित किया जाना चाहिए:

In [23]: import abc 

In [24]: class Combined(metaclass=M1 + abc.ABCMeta): 
    ...:  pass 
    ...: 
At M1 creation 
संबंधित मुद्दे