मुख्य सामग्री पर जाएँ

Python मेटाक्लासेस का परिचय

इस ट्यूटोरियल में जानें कि मेटाक्लासेस क्या होते हैं, उन्हें Python में कैसे लागू किया जाता है, और कस्टम मेटाक्लास कैसे बनाए जाते हैं।
· 6 मि॰ पढ़ें

AI के साथ खोजें

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

Python में सब कुछ ऑब्जेक्ट है

class TestClass():
    pass

my_test_class = TestClass()
print(my_test_class)
<__main__.TestClass object at 0x7f6fcc6bf908>

Python क्लासेस को डायनेमिक रूप से बनाया जा सकता है

Python में type हमें किसी ऑब्जेक्ट का प्रकार पता करने देता है। हम ऊपर बनाए गए ऑब्जेक्ट का प्रकार जाँच सकते हैं।

type(TestClass)
type
type(type)
type

रुकिए, यह क्या हुआ? हम उम्मीद करते थे कि ऊपर बनाए गए ऑब्जेक्ट का प्रकार class होगा, लेकिन ऐसा नहीं है। इस विचार को थामे रखें—इसे आगे कवर करेंगे। हम यह भी देखते हैं कि type का प्रकार भी type ही है। यह type का एक इंस्टेंस है। type का एक और जादुई काम यह है कि यह हमें क्लासेस को डायनेमिक रूप से बनाने देता है। नीचे देखें हम यह कैसे करेंगे। नीचे दिखाए गए DataCamp क्लास को type का उपयोग करके इस तरह बनाया जाएगा:

class DataCamp():
    pass
DataCampClass = type('DataCamp', (), {})
print(DataCampClass)
print(DataCamp())
<class '__main__.DataCamp'>
<__main__.DataCamp object at 0x7f6fcc66e358>

ऊपर के उदाहरण में DataCamp क्लास का नाम है जबकि DataCampClass वह वेरिएबल है जो क्लास का रेफरेंस रखता है। type का उपयोग करते समय हम डिक्शनरी के माध्यम से क्लास के एट्रीब्यूट्स पास कर सकते हैं, जैसा नीचे दिखाया गया है:

PythonClass = type('PythonClass', (), {'start_date': 'August 2018', 'instructor': 'John Doe'} )
print(PythonClass.start_date, PythonClass.instructor)
print(PythonClass)
August 2018 John Doe
<class '__main__.PythonClass'>

यदि हम चाहते हैं कि हमारा PythonClass, DataCamp क्लास से इनहेरिट करे, तो type से क्लास परिभाषित करते समय उसे दूसरे आर्ग्युमेंट में पास करते हैं

PythonClass = type('PythonClass', (DataCamp,), {'start_date': 'August 2018', 'instructor': 'John Doe'} )
print(PythonClass)
<class '__main__.PythonClass'>

अब जब ये दोनों अवधारणाएँ स्पष्ट हैं, तो समझ आता है कि Python, क्लासेस को मेटाक्लास के द्वारा बनाता है। हमने देखा कि Python में सब कुछ ऑब्जेक्ट है, और ये ऑब्जेक्ट्स मेटाक्लासेस द्वारा बनाए जाते हैं। जब भी हम class लिखकर कोई क्लास बनाते हैं, परदे के पीछे एक मेटाक्लास वह क्लास बनाता है। हमने ऊपर type को यह करते हुए देखा। यह उसी तरह है जैसे str स्ट्रिंग्स बनाता है और int इंटीजर बनाता है। Python में ___class__ एट्रीब्यूट हमें वर्तमान इंस्टेंस का प्रकार जाँचने देता है। चलिए नीचे एक स्ट्रिंग बनाते हैं और उसका प्रकार देखते हैं।

article = 'metaclasses'
article.__class__
str

हम type(article) का उपयोग करके भी प्रकार जाँच सकते हैं।

type(article)
str

जब हम str का प्रकार जाँचते हैं, तो पाते हैं कि वह भी type है।

type(str)
type

जब हम float, int, list, tuple और dict के प्रकार जाँचते हैं, तो समान आउटपुट मिलता है। इसका कारण यह है कि ये सारे ऑब्जेक्ट्स type प्रकार के हैं।

print(type(list),type(float), type(dict), type(tuple))
<class 'type'> <class 'type'> <class 'type'> <class 'type'>

हमने देखा कि type क्लासेस बनाता है। इसलिए जब हम __class__ का __class__ जाँचते हैं, तो यह type ही लौटाएगा।

article.__class__.__class__
type

कस्टम मेटाक्लासेस बनाना

Python में हम क्लास परिभाषा में metaclass कीवर्ड पास करके क्लास-निर्माण की प्रक्रिया को कस्टमाइज़ कर सकते हैं। यह किसी ऐसी क्लास से इनहेरिट करके भी किया जा सकता है जिसमें यह कीवर्ड पहले से पास किया गया हो।

class MyMeta(type):
    pass

class MyClass(metaclass=MyMeta):
    pass

class MySubclass(MyClass):
    pass

नीचे हम देखते हैं कि MyMeta क्लास का प्रकार type है और MyClass तथा MySubClass का प्रकार MyMeta है।

print(type(MyMeta))
print(type(MyClass))
print(type(MySubclass))
<class 'type'>
<class '__main__.MyMeta'>
<class '__main__.MyMeta'>

जब कोई क्लास परिभाषित की जाती है और कोई मेटाक्लास निर्दिष्ट नहीं होता, तो डिफ़ॉल्ट type मेटाक्लास उपयोग में आता है। यदि कोई मेटाक्लास दिया गया है और वह type() का इंस्टेंस नहीं है, तो उसे सीधे मेटाक्लास के रूप में उपयोग किया जाता है।

__new__ और __init__

मेटाक्लासेस नीचे दिखाए गए दो तरीकों में से किसी एक से भी परिभाषित किए जा सकते हैं। इनके बीच का अंतर नीचे समझाया गया है।

class MetaOne(type):
    def __new__(cls, name, bases, dict):
        pass

class MetaTwo(type):
    def __init__(self, name, bases, dict):
        pass

__new__ का उपयोग तब होता है जब क्लास बनने से पहले dict या bases ट्यूपल्स परिभाषित करने होते हैं। __new__ का रिटर्न मान सामान्यतः cls का एक इंस्टेंस होता है। __new__ इम्यूटेबल टाइप्स की सबक्लासेस को इंस्टेंस निर्माण कस्टमाइज़ करने देता है। कस्टम मेटाक्लासेस में इसे ओवरराइड करके क्लास निर्माण को कस्टमाइज़ किया जा सकता है। __init__ आमतौर पर ऑब्जेक्ट बनने के बाद उसे इनिशियलाइज़ करने के लिए कॉल किया जाता है।

मेटाक्लास का __call__ मेथड

आधिकारिक डॉक्स के अनुसार, हम मेटाक्लास में कस्टम __call__() मेथड परिभाषित करके अन्य क्लास मेथड्स को भी ओवरराइड कर सकते हैं, जो क्लास कॉल होने पर कस्टम व्यवहार की अनुमति देता है।

मेटाक्लास का __prepare__ मेथड

Python के डेटा मॉडल डॉक्स के अनुसार

उपयुक्त मेटाक्लास की पहचान हो जाने के बाद, क्लास नेमस्पेस तैयार किया जाता है। यदि मेटाक्लास में __prepare__ एट्रीब्यूट है, तो उसे इस प्रकार कॉल किया जाता है: namespace = metaclass.__prepare__(name, bases, **kwds) (जहाँ अतिरिक्त कीवर्ड आर्ग्युमेंट्स, यदि हों, क्लास परिभाषा से आते हैं)। यदि मेटाक्लास में __prepare__ एट्रीब्यूट नहीं है, तो क्लास नेमस्पेस को एक खाली ऑर्डर्ड मैपिंग के रूप में इनिशियलाइज़ किया जाता है। - docs.python.org

मेटाक्लास का उपयोग करके सिंगलटन डिज़ाइन

यह एक डिज़ाइन पैटर्न है जो किसी क्लास के इंस्टैंसिएशन को केवल एक ऑब्जेक्ट तक सीमित करता है। यह, उदाहरण के लिए, डेटाबेस से कनेक्ट करने वाली क्लास डिज़ाइन करते समय उपयोगी हो सकता है। आप कनेक्शन क्लास का सिर्फ एक ही इंस्टेंस रखना चाह सकते हैं।

class SingletonMeta(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(SingletonMeta,cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class SingletonClass(metaclass=SingletonMeta):
    pass

निष्कर्ष

इस लेख में, हमने जाना कि मेटाक्लासेस क्या हैं और उन्हें अपने Python प्रोग्रामिंग में कैसे लागू किया जा सकता है। मेटाक्लासेस का उपयोग लॉगिंग, क्लासेस के क्रिएशन-टाइम रजिस्ट्रेशन, प्रोफाइलिंग इत्यादि में किया जा सकता है। ये काफ़ी अमूर्त अवधारणाएँ लगती हैं, और आप सोच रहे होंगे कि क्या आपको इनकी आवश्यकता है भी या नहीं। लंबे समय से Python उपयोगकर्ता Tim Peters ने इसका सबसे अच्छा उत्तर दिया है।

"Metaclasses are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don’t (the people who actually need them know with certainty that they need them, and don’t need an explanation about why).” - realpython

यदि आप Python के बारे में और सीखना चाहते हैं, तो DataCamp का Python Programming स्किल ट्रैक शुरू करें और हमारा Python Classes Tutorial देखें।

संदर्भ

लिंक एक

लिंक दो

विषय