खोज…


परिचय

मेटाक्लासेस आपको 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 का उपयोग करते हैं:

पायथन 2.x 2.7

__metaclass__ को निर्दिष्ट करने के लिए एक विशेष श्रेणी-स्तरीय विशेषता __metaclass__ का उपयोग किया जा सकता है।

class MyDummy(object):
    __metaclass__ = mytype
type(MyDummy)  # <class '__main__.mytype'>
अजगर 3.x 3.0

एक विशेष 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
पायथन 2.x 2.7
class MySingleton(object):
    __metaclass__ = SingletonType
अजगर 3.x 3.0
class MySingleton(metaclass=SingletonType):
    pass
MySingleton() is MySingleton()  # True, only one instantiation occurs

मेटाक्लस का उपयोग करना

मेटाक्लस सिंटैक्स

पायथन 2.x 2.7
class MyClass(object):
    __metaclass__ = SomeMetaclass
अजगर 3.x 3.0
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 , और अब तक यह सबसे आम मेटाक्लस है

लेकिन आपको मेटाक्लस के बारे में क्यों पता होना चाहिए? ठीक है, पायथन स्वयं काफी "हैक करने योग्य" है, और मेटाक्लास की अवधारणा महत्वपूर्ण है यदि आप मेटा-प्रोग्रामिंग जैसे उन्नत सामान कर रहे हैं या यदि आप नियंत्रित करना चाहते हैं कि आपकी कक्षाएं कैसे आरंभ की जाती हैं।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow