कस्टम मेटाक्लासेस बनाना
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 देखें।
Python में एक मेटाक्लास, क्लास का क्लास होता है जो यह परिभाषित करता है कि कोई क्लास कैसे व्यवहार करेगी। स्वयं एक क्लास, किसी मेटाक्लास का इंस्टेंस होती है। Python में कोई क्लास यह परिभाषित करती है कि उसकी इंस्टेंस कैसे व्यवहार करेगी। मेटाक्लासेस को अच्छी तरह समझने के लिए, Python क्लासेस के साथ काम करने का पूर्व अनुभव होना चाहिए। मेटाक्लासेस में गहराई से जाने से पहले, कुछ बुनियादी अवधारणाएँ साफ कर लें।
Python में सब कुछ ऑब्जेक्ट है
Python क्लासेस को डायनेमिक रूप से बनाया जा सकता है
Python में
typeहमें किसी ऑब्जेक्ट का प्रकार पता करने देता है। हम ऊपर बनाए गए ऑब्जेक्ट का प्रकार जाँच सकते हैं।रुकिए, यह क्या हुआ? हम उम्मीद करते थे कि ऊपर बनाए गए ऑब्जेक्ट का प्रकार class होगा, लेकिन ऐसा नहीं है। इस विचार को थामे रखें—इसे आगे कवर करेंगे। हम यह भी देखते हैं कि
typeका प्रकार भीtypeही है। यहtypeका एक इंस्टेंस है।typeका एक और जादुई काम यह है कि यह हमें क्लासेस को डायनेमिक रूप से बनाने देता है। नीचे देखें हम यह कैसे करेंगे। नीचे दिखाए गएDataCampक्लास कोtypeका उपयोग करके इस तरह बनाया जाएगा:ऊपर के उदाहरण में
DataCampक्लास का नाम है जबकिDataCampClassवह वेरिएबल है जो क्लास का रेफरेंस रखता है।typeका उपयोग करते समय हम डिक्शनरी के माध्यम से क्लास के एट्रीब्यूट्स पास कर सकते हैं, जैसा नीचे दिखाया गया है:यदि हम चाहते हैं कि हमारा
PythonClass,DataCampक्लास से इनहेरिट करे, तोtypeसे क्लास परिभाषित करते समय उसे दूसरे आर्ग्युमेंट में पास करते हैंअब जब ये दोनों अवधारणाएँ स्पष्ट हैं, तो समझ आता है कि Python, क्लासेस को मेटाक्लास के द्वारा बनाता है। हमने देखा कि Python में सब कुछ ऑब्जेक्ट है, और ये ऑब्जेक्ट्स मेटाक्लासेस द्वारा बनाए जाते हैं। जब भी हम
classलिखकर कोई क्लास बनाते हैं, परदे के पीछे एक मेटाक्लास वह क्लास बनाता है। हमने ऊपरtypeको यह करते हुए देखा। यह उसी तरह है जैसेstrस्ट्रिंग्स बनाता है औरintइंटीजर बनाता है। Python में___class__एट्रीब्यूट हमें वर्तमान इंस्टेंस का प्रकार जाँचने देता है। चलिए नीचे एक स्ट्रिंग बनाते हैं और उसका प्रकार देखते हैं।हम
type(article)का उपयोग करके भी प्रकार जाँच सकते हैं।जब हम
strका प्रकार जाँचते हैं, तो पाते हैं कि वह भी type है।जब हम
float,int,list,tupleऔरdictके प्रकार जाँचते हैं, तो समान आउटपुट मिलता है। इसका कारण यह है कि ये सारे ऑब्जेक्ट्सtypeप्रकार के हैं।हमने देखा कि
typeक्लासेस बनाता है। इसलिए जब हम__class__का__class__जाँचते हैं, तो यहtypeही लौटाएगा।