Python Language
Metaclasses
खोज…
परिचय
मेटाक्लासेस आपको type
मेटाक्लास की जगह जिसे नए वर्ग डिफ़ॉल्ट रूप से उपयोग करते हैं, प्रतिस्थापित करके पायथन कक्षाओं के व्यवहार को गहराई से संशोधित करने की अनुमति देते हैं।
टिप्पणियों
अपने आर्किटेक्चर को डिजाइन करते समय, विचार करें कि कई चीजें जो मेटाक्लासेस के साथ पूरी की जा सकती हैं, उन्हें अधिक सरल शब्दार्थ का उपयोग करके भी पूरा किया जा सकता है:
- पारंपरिक विरासत अक्सर पर्याप्त से अधिक है।
- क्लास डेकोरेटर्स एक एड-हॉक दृष्टिकोण पर कक्षाओं में मिश्रण-इन कार्यक्षमता कर सकते हैं।
- अजगर 3.6
__init_subclass__()
परिचय देता है जो एक वर्ग को अपने उपवर्ग के निर्माण में भाग लेने की अनुमति देता है।
मूल मेटाक्लस
जब type
को तीन तर्कों के साथ कहा जाता है तो यह (मेटा) वर्ग के रूप में व्यवहार करता है, और एक नया उदाहरण बनाता है, अर्थात। यह एक नया वर्ग / प्रकार तैयार करता है।
Dummy = type('OtherDummy', (), dict(x=1))
Dummy.__class__ # <type 'type'>
Dummy().__class__.__class__ # <type 'type'>
कस्टम मेटाक्लस बनाने के लिए type
को उप-वर्ग करना संभव है।
class mytype(type):
def __init__(cls, name, bases, dict):
# call the base initializer
type.__init__(cls, name, bases, dict)
# perform custom initialization...
cls.__custom_attribute__ = 2
अब, हम एक नए कस्टम है mytype
metaclass जो के रूप में एक ही तरीके से कक्षाएं बनाने के लिए इस्तेमाल किया जा सकता type
।
MyDummy = mytype('MyDummy', (), dict(x=2))
MyDummy.__class__ # <class '__main__.mytype'>
MyDummy().__class__.__class__ # <class '__main__.mytype'>
MyDummy.__custom_attribute__ # 2
जब हम class
कीवर्ड का उपयोग करके एक नया वर्ग बनाते हैं तो मेटाक्लस मूलभूत रूप से बेसकेल्स पर आधारित होता है।
>>> class Foo(object):
... pass
>>> type(Foo)
type
उपर्युक्त उदाहरण में केवल बेसकलेस object
इसलिए हमारी मेटाक्लस object
का प्रकार होगा, जो कि type
। यह डिफ़ॉल्ट को ओवरराइड करना संभव है, हालांकि यह इस बात पर निर्भर करता है कि हम पायथन 2 या पायथन 3 का उपयोग करते हैं:
__metaclass__
को निर्दिष्ट करने के लिए एक विशेष श्रेणी-स्तरीय विशेषता __metaclass__
का उपयोग किया जा सकता है।
class MyDummy(object):
__metaclass__ = mytype
type(MyDummy) # <class '__main__.mytype'>
एक विशेष metaclass
कीवर्ड तर्क मेटाक्लास निर्दिष्ट करता है।
class MyDummy(metaclass=mytype):
pass
type(MyDummy) # <class '__main__.mytype'>
वर्ग घोषणा में कोई भी कीवर्ड तर्क ( metaclass
को छोड़कर) metaclass
को पास कर दिया जाएगा। इस प्रकार class MyDummy(metaclass=mytype, x=2)
mytype
कंस्ट्रक्टर के लिए एक कीवर्ड तर्क के रूप में x=2
पास करेगा।
अधिक विवरण के लिए अजगर मेटा-कक्षाओं का यह गहराई से वर्णन पढ़ें।
मेटाक्लासेस का उपयोग करने वाले एकल
एक सिंगलटन एक ऐसा पैटर्न है जो एक वर्ग के तात्कालिकता को एक उदाहरण / वस्तु के लिए प्रतिबंधित करता है। अजगर सिंगलटन डिजाइन पैटर्न के बारे में अधिक जानकारी के लिए, यहां देखें।
class SingletonType(type):
def __call__(cls, *args, **kwargs):
try:
return cls.__instance
except AttributeError:
cls.__instance = super(SingletonType, cls).__call__(*args, **kwargs)
return cls.__instance
class MySingleton(object):
__metaclass__ = SingletonType
class MySingleton(metaclass=SingletonType):
pass
MySingleton() is MySingleton() # True, only one instantiation occurs
मेटाक्लस का उपयोग करना
मेटाक्लस सिंटैक्स
class MyClass(object):
__metaclass__ = SomeMetaclass
class MyClass(metaclass=SomeMetaclass):
pass
अजगर 2 और 3 के साथ संगतता six
import six
class MyClass(six.with_metaclass(SomeMetaclass)):
pass
मेटाक्लासेस के साथ कस्टम कार्यक्षमता
मेटाक्लासेस में कार्यक्षमता को बदला जा सकता है ताकि जब भी कोई वर्ग बनाया जाए, तो मानक उत्पादन के लिए एक स्ट्रिंग मुद्रित किया जाता है, या एक अपवाद फेंक दिया जाता है। यह मेटाक्लास निर्मित की जा रही कक्षा के नाम को प्रिंट करेगा।
class VerboseMetaclass(type):
def __new__(cls, class_name, class_parents, class_dict):
print("Creating class ", class_name)
new_class = super().__new__(cls, class_name, class_parents, class_dict)
return new_class
आप इस तरह के रूपक का उपयोग कर सकते हैं:
class Spam(metaclass=VerboseMetaclass):
def eggs(self):
print("[insert example string here]")
s = Spam()
s.eggs()
मानक उत्पादन होगा:
Creating class Spam
[insert example string here]
मेटाक्लासेस का परिचय
मेटाक्लास क्या है?
पायथन में, सब कुछ एक वस्तु है: पूर्णांक, तार, सूची, यहां तक कि फ़ंक्शन और कक्षाएं स्वयं ऑब्जेक्ट हैं। और प्रत्येक वस्तु एक वर्ग का एक उदाहरण है।
ऑब्जेक्ट x के वर्ग की जांच करने के लिए, कोई व्यक्ति type(x)
कह सकता है, इसलिए:
>>> type(5)
<type 'int'>
>>> type(str)
<type 'type'>
>>> type([1, 2, 3])
<type 'list'>
>>> class C(object):
... pass
...
>>> type(C)
<type 'type'>
अजगर में अधिकांश वर्ग type
उदाहरण हैं। type
खुद भी एक वर्ग है। ऐसे वर्ग जिनके उदाहरण वर्ग भी होते हैं, मेटाक्लास कहलाते हैं।
सबसे सरल मेटाक्लास
ठीक है, इसलिए पाइथन में पहले से ही एक मेटाक्लस है: type
। क्या हम एक और बना सकते हैं?
class SimplestMetaclass(type):
pass
class MyClass(object):
__metaclass__ = SimplestMetaclass
यह किसी भी कार्यक्षमता को नहीं जोड़ता है, लेकिन यह एक नया मेटाक्लस है, देखें कि MyClass अब SimpleestMatacac का एक उदाहरण है:
>>> type(MyClass)
<class '__main__.SimplestMetaclass'>
एक मेटाक्लास जो कुछ करता है
एक metaclass जो कुछ आम तौर पर करता है ओवरराइड करता है type
के __new__
, मूल कॉल करने से पहले संशोधित करने के लिए वर्ग के कुछ गुण बनाया जाना, __new__
जो वर्ग बनाता है:
class AnotherMetaclass(type):
def __new__(cls, name, parents, dct):
# cls is this class
# name is the name of the class to be created
# parents is the list of the class's parent classes
# dct is the list of class's attributes (methods, static variables)
# here all of the attributes can be modified before creating the class, e.g.
dct['x'] = 8 # now the class will have a static variable x = 8
# return value is the new class. super will take care of that
return super(AnotherMetaclass, cls).__new__(cls, name, parents, dct)
डिफ़ॉल्ट मेटाक्लस
आपने सुना होगा कि पायथन में सब कुछ एक वस्तु है। यह सच है, और सभी वस्तुओं में एक वर्ग है:
>>> type(1)
int
शाब्दिक 1 int
उदाहरण है। एक वर्ग घोषित करें:
>>> class Foo(object):
... pass
...
अब इसे तुरंत करने देता है:
>>> bar = Foo()
bar
का वर्ग क्या है?
>>> type(bar)
Foo
अच्छा, bar
Foo
का एक उदाहरण है। लेकिन Foo
की कक्षा क्या है?
>>> type(Foo)
type
ठीक है, Foo
खुद ही एक type
उदाहरण है। type
बारे में कैसे?
>>> type(type)
type
तो एक मेटाक्लस क्या है? अभी के लिए यह दिखावा करता है कि यह एक वर्ग के वर्ग के लिए सिर्फ एक फैंसी नाम है। टेकअवे:
- अजगर में सब कुछ एक वस्तु है, इसलिए सब कुछ एक वर्ग है
- वर्ग के वर्ग को मेटाक्लास कहा जाता है
- डिफ़ॉल्ट मेटाक्लस
type
, और अब तक यह सबसे आम मेटाक्लस है
लेकिन आपको मेटाक्लस के बारे में क्यों पता होना चाहिए? ठीक है, पायथन स्वयं काफी "हैक करने योग्य" है, और मेटाक्लास की अवधारणा महत्वपूर्ण है यदि आप मेटा-प्रोग्रामिंग जैसे उन्नत सामान कर रहे हैं या यदि आप नियंत्रित करना चाहते हैं कि आपकी कक्षाएं कैसे आरंभ की जाती हैं।