मेटाक्लासेस के लिए कुछ (ठोस) उपयोग-मामले क्या हैं?


118

मेरे पास एक दोस्त है जो मेटाक्लस का उपयोग करना पसंद करता है, और नियमित रूप से उन्हें समाधान के रूप में पेश करता है।

मैं मन का हूं कि आपको लगभग कभी भी मेटाक्लासेस का उपयोग करने की आवश्यकता नहीं है। क्यों? क्योंकि मैं समझती हूं कि यदि आप कक्षा में ऐसा कुछ कर रहे हैं, तो आपको संभवतः किसी वस्तु पर करना चाहिए। और एक छोटा नया स्वरूप / रिफ्लेक्टर क्रम में है।

मेटाक्लास का उपयोग करने में सक्षम होने के कारण बहुत से लोगों ने कक्षाओं का उपयोग किसी तरह की दूसरी दर वस्तु के रूप में किया है, जो कि मेरे लिए विनाशकारी लगता है। क्या प्रोग्रामिंग को मेटा-प्रोग्रामिंग द्वारा प्रतिस्थापित किया जाना है? क्लास डेकोरेटर्स के अतिरिक्त ने दुर्भाग्य से इसे और अधिक स्वीकार्य बना दिया है।

तो कृपया, मैं पायथन में मेटाक्लासेस के लिए आपके वैध (ठोस) उपयोग के मामलों को जानने के लिए बेताब हूं। या प्रबुद्ध होने के रूप में क्यों उत्परिवर्तित वर्ग कभी-कभी वस्तुओं को बदलने से बेहतर है।

मैं प्रारम्भ करूँगा:

कभी-कभी तीसरे पक्ष के पुस्तकालय का उपयोग करते समय एक निश्चित तरीके से कक्षा को बदलने में सक्षम होना उपयोगी होता है।

(यह एकमात्र ऐसा मामला है जिसके बारे में मैं सोच सकता हूं, और यह ठोस नहीं है)


3
यह एक बड़ा सवाल है। नीचे दिए गए जवाबों को देखते हुए, यह बिल्कुल स्पष्ट है कि मेटाक्लासेस के लिए ठोस उपयोग जैसी कोई चीज नहीं है।
मार्कस ओटोसन

जवाबों:


25

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

class PlottingInteractive:
    add_slice = wrap_pylab_newplot(add_slice)

यह विधि एपीआई परिवर्तनों और इतने पर नहीं रहती है, लेकिन वर्ग विशेषताओं को __init__फिर से सेट करने से पहले वर्ग विशेषताओं पर पुनरावृत्ति करने वाला एक वर्ग अधिक कुशल है और चीजों को अद्यतित रखता है:

class _Interactify(type):
    def __init__(cls, name, bases, d):
        super(_Interactify, cls).__init__(name, bases, d)
        for base in bases:
            for attrname in dir(base):
                if attrname in d: continue # If overridden, don't reset
                attr = getattr(cls, attrname)
                if type(attr) == types.MethodType:
                    if attrname.startswith("add_"):
                        setattr(cls, attrname, wrap_pylab_newplot(attr))
                    elif attrname.startswith("set_"):
                        setattr(cls, attrname, wrap_pylab_show(attr))

बेशक, ऐसा करने के लिए बेहतर तरीके हो सकते हैं, लेकिन मैंने इसे प्रभावी होने के लिए पाया है। बेशक, यह भी किया जा सकता है __new__या __init__है, लेकिन इस समाधान मैं सबसे सरल पाया था।


103

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

अधिकांश मेटाक्लासेस मैंने दो चीजों में से एक को देखा है:

  1. पंजीकरण (डेटा संरचना में एक वर्ग जोड़ना):

    models = {}
    
    class ModelMetaclass(type):
        def __new__(meta, name, bases, attrs):
            models[name] = cls = type.__new__(meta, name, bases, attrs)
            return cls
    
    class Model(object):
        __metaclass__ = ModelMetaclass

    जब भी आप उपवर्ग करते हैं Model, आपकी कक्षा modelsशब्दकोश में पंजीकृत होती है :

    >>> class A(Model):
    ...     pass
    ...
    >>> class B(A):
    ...     pass
    ...
    >>> models
    {'A': <__main__.A class at 0x...>,
     'B': <__main__.B class at 0x...>}

    यह क्लास डेकोरेटर्स के साथ भी किया जा सकता है:

    models = {}
    
    def model(cls):
        models[cls.__name__] = cls
        return cls
    
    @model
    class A(object):
        pass

    या एक स्पष्ट पंजीकरण समारोह के साथ:

    models = {}
    
    def register_model(cls):
        models[cls.__name__] = cls
    
    class A(object):
        pass
    
    register_model(A)

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

    वैसे भी, इस मामले में मेटाक्लासिस का लाभ विरासत है, क्योंकि वे किसी भी उपवर्ग के लिए काम करते हैं, जबकि अन्य समाधान केवल उपवर्गों के लिए स्पष्ट रूप से सजाए गए या पंजीकृत होते हैं।

    >>> class B(A):
    ...     pass
    ...
    >>> models
    {'A': <__main__.A class at 0x...> # No B :(
  2. Refactoring (वर्ग विशेषताओं को संशोधित करना या नए जोड़ना):

    class ModelMetaclass(type):
        def __new__(meta, name, bases, attrs):
            fields = {}
            for key, value in attrs.items():
                if isinstance(value, Field):
                    value.name = '%s.%s' % (name, key)
                    fields[key] = value
            for base in bases:
                if hasattr(base, '_fields'):
                    fields.update(base._fields)
            attrs['_fields'] = fields
            return type.__new__(meta, name, bases, attrs)
    
    class Model(object):
        __metaclass__ = ModelMetaclass

    जब भी आप Modelकुछ Fieldविशेषताओं को उपवर्गित करते हैं और परिभाषित करते हैं, तो उन्हें अपने नामों (उदाहरण के लिए अधिक जानकारीपूर्ण त्रुटि संदेश) के साथ इंजेक्ट किया जाता है, और एक _fieldsशब्दकोश में वर्गीकृत किया जाता है (आसान पुनरावृत्ति के लिए, सभी वर्ग विशेषताओं और इसके सभी आधार वर्गों के माध्यम से देखने के लिए बिना हर बार विशेषताएं):

    >>> class A(Model):
    ...     foo = Integer()
    ...
    >>> class B(A):
    ...     bar = String()
    ...
    >>> B._fields
    {'foo': Integer('A.foo'), 'bar': String('B.bar')}

    फिर, यह एक वर्ग सज्जाकार के साथ (विरासत के बिना) किया जा सकता है:

    def model(cls):
        fields = {}
        for key, value in vars(cls).items():
            if isinstance(value, Field):
                value.name = '%s.%s' % (cls.__name__, key)
                fields[key] = value
        for base in cls.__bases__:
            if hasattr(base, '_fields'):
                fields.update(base._fields)
        cls._fields = fields
        return cls
    
    @model
    class A(object):
        foo = Integer()
    
    class B(A):
        bar = String()
    
    # B.bar has no name :(
    # B._fields is {'foo': Integer('A.foo')} :(

    या स्पष्ट रूप से:

    class A(object):
        foo = Integer('A.foo')
        _fields = {'foo': foo} # Don't forget all the base classes' fields, too!

    हालांकि, पठनीय और बनाए रखने योग्य गैर-मेटा प्रोग्रामिंग के लिए आपकी वकालत के विपरीत, यह बहुत अधिक बोझिल, निरर्थक और त्रुटि प्रवण है:

    class B(A):
        bar = String()
    
    # vs.
    
    class B(A):
        bar = String('bar')
        _fields = {'B.bar': bar, 'A.foo': A.foo}

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

class Metaclass(type):
    def __new__(meta, name, bases, attrs):
        return type.__new__(meta, 'foo', (int,), attrs)

class Baseclass(object):
    __metaclass__ = Metaclass

class A(Baseclass):
    pass

class B(A):
    pass

print A.__name__ # foo
print B.__name__ # foo
print issubclass(B, A)   # False
print issubclass(B, int) # True

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

वैसे भी, पायथन 3 में, मेटाक्लासेस की भी __prepare__विधि है, जो आपको क्लास बॉडी का मूल्यांकन मैपिंग के अलावा अन्य में करने देता है dict, इस प्रकार ऑर्डर किए गए विशेषताओं, अतिभारित विशेषताओं और अन्य दुष्ट शांत सामानों का समर्थन करता है:

import collections

class Metaclass(type):

    @classmethod
    def __prepare__(meta, name, bases, **kwds):
        return collections.OrderedDict()

    def __new__(meta, name, bases, attrs, **kwds):
        print(list(attrs))
        # Do more stuff...

class A(metaclass=Metaclass):
    x = 1
    y = 2

# prints ['x', 'y'] rather than ['y', 'x']

 

class ListDict(dict):
    def __setitem__(self, key, value):
        self.setdefault(key, []).append(value)

class Metaclass(type):

    @classmethod
    def __prepare__(meta, name, bases, **kwds):
        return ListDict()

    def __new__(meta, name, bases, attrs, **kwds):
        print(attrs['foo'])
        # Do more stuff...

class A(metaclass=Metaclass):

    def foo(self):
        pass

    def foo(self, x):
        pass

# prints [<function foo at 0x...>, <function foo at 0x...>] rather than <function foo at 0x...>

आप तर्क दे सकते हैं कि सृजन काउंटरों के साथ विशेषताओं को प्राप्त किया जा सकता है, और ओवरलोडिंग को डिफ़ॉल्ट तर्कों के साथ अनुकरण किया जा सकता है:

import itertools

class Attribute(object):
    _counter = itertools.count()
    def __init__(self):
        self._count = Attribute._counter.next()

class A(object):
    x = Attribute()
    y = Attribute()

A._order = sorted([(k, v) for k, v in vars(A).items() if isinstance(v, Attribute)],
                  key = lambda (k, v): v._count)

 

class A(object):

    def _foo0(self):
        pass

    def _foo1(self, x):
        pass

    def foo(self, x=None):
        if x is None:
            return self._foo0()
        else:
            return self._foo1(x)

बहुत अधिक बदसूरत होने के अलावा, यह भी कम लचीला है: क्या होगा यदि आप पूर्णांक और स्ट्रिंग्स जैसे शाब्दिक विशेषताओं का आदेश देना चाहते हैं? क्या होगा यदि इसके Noneलिए एक वैध मूल्य है x?

यहाँ पहली समस्या को हल करने का एक रचनात्मक तरीका है:

import sys

class Builder(object):
    def __call__(self, cls):
        cls._order = self.frame.f_code.co_names
        return cls

def ordered():
    builder = Builder()
    def trace(frame, event, arg):
        builder.frame = frame
        sys.settrace(None)
    sys.settrace(trace)
    return builder

@ordered()
class A(object):
    x = 1
    y = 'foo'

print A._order # ['x', 'y']

और यहाँ एक दूसरे को हल करने का रचनात्मक तरीका है:

_undefined = object()

class A(object):

    def _foo0(self):
        pass

    def _foo1(self, x):
        pass

    def foo(self, x=_undefined):
        if x is _undefined:
            return self._foo0()
        else:
            return self._foo1(x)

लेकिन यह बहुत है, एक साधारण मेटाक्लास (विशेष रूप से पहला वाला, जो वास्तव में आपके मस्तिष्क को पिघला देता है) की तुलना में म्यू-वूडू-एर। मेरा कहना है, आप मेटाक्लस को अपरिचित और प्रति-सहज के रूप में देखते हैं, लेकिन आप उन्हें प्रोग्रामिंग भाषाओं में विकास के अगले चरण के रूप में भी देख सकते हैं: आपको बस अपनी मानसिकता को समायोजित करना होगा। आखिरकार, आप संभवतः C में सब कुछ कर सकते हैं, जिसमें फ़ंक्शन पॉइंटर्स के साथ एक संरचना को परिभाषित करना और इसे अपने कार्यों के लिए पहले तर्क के रूप में पारित करना शामिल है। पहली बार C ++ देखने वाला व्यक्ति कह सकता है, "यह जादू क्या है? संकलक क्यों गुजर रहा हैthisतरीकों के लिए, लेकिन नियमित और स्थिर कार्यों के लिए नहीं? यह स्पष्ट होना बेहतर है और अपने तर्कों के बारे में बात करें "। लेकिन फिर, ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग बहुत ही शक्तिशाली है एक बार जब आप इसे प्राप्त करते हैं, और इसलिए यह है, उह ... क्वैसी-पहलू-उन्मुख प्रोग्रामिंग, मुझे लगता है। और एक बार आप। मेटाक्लास को समझें, वे वास्तव में बहुत सरल हैं, इसलिए सुविधाजनक होने पर उनका उपयोग क्यों न करें?

और अंत में, मेटाक्लास रेड हैं, और प्रोग्रामिंग मजेदार होनी चाहिए। मानक प्रोग्रामिंग कंस्ट्रक्शन और डिज़ाइन पैटर्न का उपयोग करना हर समय उबाऊ और उदासीन है, और आपकी कल्पना में बाधा डालता है। थोड़ा और जियो! यहाँ सिर्फ आपके लिए एक मेटामेकाॅक्लस है।

class MetaMetaclass(type):
    def __new__(meta, name, bases, attrs):
        def __new__(meta, name, bases, attrs):
            cls = type.__new__(meta, name, bases, attrs)
            cls._label = 'Made in %s' % meta.__name__
            return cls 
        attrs['__new__'] = __new__
        return type.__new__(meta, name, bases, attrs)

class China(type):
    __metaclass__ = MetaMetaclass

class Taiwan(type):
    __metaclass__ = MetaMetaclass

class A(object):
    __metaclass__ = China

class B(object):
    __metaclass__ = Taiwan

print A._label # Made in China
print B._label # Made in Taiwan

संपादित करें

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


5
यह एक महान जवाब है, इसे लिखने के लिए समय और कई उदाहरण देने के लिए धन्यवाद
चेन ए।

"... इस मामले में मेटाक्लासेस का लाभ विरासत में है, क्योंकि वे किसी भी उपवर्ग के लिए काम करते हैं" - पायथन 3 में नहीं, मुझे लगता है? मुझे लगता है कि यह केवल पायथन 2 में काम करता है क्योंकि कोई भी बच्चा वर्ग __metaclass__विशेषता प्राप्त करता है, लेकिन यह विशेषता अब पायथन 3 में विशेष नहीं है। क्या इस तरह से "बच्चों की कक्षाएं भी माता-पिता के मेटाक्लास द्वारा बनाई गई हैं" पायथन 3 में काम करते हैं ?
फोर्सब्रू

2
यह पायथन 3 के लिए भी सही है, क्योंकि ए से विरासत में मिला एक वर्ग बी, जिसका मेटाक्लास एम है, एम का भी एक प्रकार है, इसलिए जब बी का मूल्यांकन किया जाता है, तो एम इसे बनाने के लिए आमंत्रित किया जाता है, और यह आपको प्रभावी रूप से अनुमति देता है। "किसी भी उपवर्ग पर काम करने के लिए" (ए के)। यह कहने के बाद कि, पायथन 3.6 ने बहुत सरलता से पेश किया init_subclass, इसलिए अब आप एक बेसकलैस में उपवर्गों में फेरबदल कर सकते हैं, और अब उस उद्देश्य के लिए मेटाक्लस की आवश्यकता नहीं है।
दान जिटिक

यह शानदार है, मैंने मेटाक्लासेस पर बहुत सारे ब्लॉग पोस्ट पढ़े, केवल यह ही पेशेवरों और विपक्ष और मेटाक्लास के विकल्पों को जानता है।
ospider

36

मेटाक्लास का उद्देश्य वर्ग / वस्तु भेद को मेटाक्लस / वर्ग से बदलना नहीं है - यह वर्ग परिभाषाओं के व्यवहार को बदलना है (और इस प्रकार उनके उदाहरण)। प्रभावी रूप से यह क्लास स्टेटमेंट के व्यवहार को उन तरीकों से बदलना है जो आपके विशेष डोमेन के लिए डिफ़ॉल्ट से अधिक उपयोगी हो सकते हैं। जिन चीजों के लिए मैंने उनका उपयोग किया है वे हैं:

  • ट्रैकिंग उपवर्ग, आमतौर पर संचालकों को पंजीकृत करने के लिए। प्लगइन स्टाइल सेटअप का उपयोग करते समय यह आसान है, जहां आप किसी विशेष चीज़ के लिए एक हैंडलर को केवल उपवर्ग और कुछ वर्ग विशेषताओं को सेट करके रजिस्टर करना चाहते हैं। जैसे। मान लें कि आप विभिन्न संगीत प्रारूपों के लिए एक हैंडलर लिखते हैं, जहाँ प्रत्येक वर्ग अपने प्रकार के लिए उपयुक्त तरीके (प्ले / टैग इत्यादि) लागू करता है। नए प्रकार के लिए एक हैंडलर जोड़ना बनता है:

    class Mp3File(MusicFile):
        extensions = ['.mp3']  # Register this type as a handler for mp3 files
        ...
        # Implementation of mp3 methods go here

    मेटाक्लास तब {'.mp3' : MP3File, ... }आदि के शब्दकोश को बनाए रखता है , और जब आप किसी फैक्ट्री फ़ंक्शन के माध्यम से हैंडलर का अनुरोध करते हैं तो उपयुक्त प्रकार की एक वस्तु का निर्माण करते हैं।

  • बदलता व्यवहार। आप कुछ विशेषताओं के लिए एक विशेष अर्थ संलग्न करना चाह सकते हैं, जिसके परिणामस्वरूप वे मौजूद होने पर परिवर्तित व्यवहार करते हैं। उदाहरण के लिए, आप नाम के साथ तरीकों के लिए देखने के लिए चाहते हो सकता है _get_fooऔर _set_fooऔर पारदर्शी उन्हें गुण में बदलने का। एक वास्तविक दुनिया के उदाहरण के रूप में, यहां एक नुस्खा है जो मैंने अधिक सी-जैसे संरचना परिभाषाएं देने के लिए लिखा था। मेटाक्लास का उपयोग घोषित वस्तुओं को एक संरचनात्मक प्रारूप स्ट्रिंग में बदलने, विरासत को संभालने आदि के लिए किया जाता है, और इससे निपटने में सक्षम वर्ग का उत्पादन करता है।

    अन्य वास्तविक दुनिया उदाहरण के लिए, जैसे विभिन्न ORMs पर एक नज़र ले SQLAlchemy के ORM या sqlobject । फिर, उद्देश्य एक विशेष अर्थ के साथ परिभाषा (यहां एसक्यूएल स्तंभ परिभाषाएं) की व्याख्या करना है।


3
खैर, हाँ, ट्रैकिंग उपवर्ग। लेकिन आप ऐसा कभी क्यों चाहेंगे? आपका उदाहरण सिर्फ register_music_file (Mp3File, ['.mp3']] के लिए निहित है, और स्पष्ट तरीका अधिक पठनीय और बनाए रखने योग्य है। यह उन बुरे मामलों का एक उदाहरण है जिनके बारे में मैं बात कर रहा हूं।
अली अफसर

ओआरएम मामले के बारे में, क्या आप टेबल को परिभाषित करने के वर्ग-आधारित तरीके, या मैप की गई वस्तुओं पर मेटाक्लस के बारे में बात कर रहे हैं। क्योंकि SQLAlchemy किसी भी वर्ग के लिए (सही तरीके से) मैप कर सकता है (और मैं यह मान रहा हूं कि यह उस गतिविधि के लिए मेटाक्लस का उपयोग नहीं करता है)।
अली अफसर

10
मैं हर उपवर्ग के लिए अतिरिक्त पंजीकरण विधियों की आवश्यकता के बजाय अधिक घोषणात्मक शैली पसंद करता हूं - अगर सब कुछ एक ही स्थान पर लिपटे हों तो बेहतर है।
ब्रायन

Sqlalchemy के लिए, मैं ज्यादातर घोषणात्मक परत के बारे में सोच रहा हूं, इसलिए शायद sqlobject एक बेहतर उदाहरण है। हालाँकि, आंतरिक रूप से उपयोग किए जाने वाले मेटाक्लासेस अर्थ को घोषित करने के लिए विशेष विशेषताओं की समान पुनर्व्याख्या के उदाहरण भी हैं।
ब्रायन

2
क्षमा करें, SO समयबाह्य परिदृश्य में मेरा एक अनुमान समाप्त हो गया। मुझे घोषणापत्र के लिए कक्षाएं लगभग एक घृणित लगती हैं। मुझे पता है कि लोग इसे पसंद करते हैं, और यह स्वीकार किया गया व्यवहार है। लेकिन (अनुभव से) मुझे पता है कि यह उस स्थिति में अनुपयोगी है जहां आप संयुक्त राष्ट्र की घोषणा करना चाहते हैं। एक वर्ग को अनरजिस्टर्ड करना कठिन है
अली अफसर

17

आइए टिम पीटर के क्लासिक उद्धरण के साथ शुरू करें:

Metaclasses 99% से अधिक गहरा जादू है, इसके बारे में उपयोगकर्ताओं को कभी भी चिंता करनी चाहिए। यदि आप आश्चर्य करते हैं कि क्या आपको उनकी आवश्यकता है, तो आप नहीं करते हैं (वे लोग जिन्हें वास्तव में उनकी आवश्यकता है वे निश्चितता के साथ जानते हैं कि उन्हें उनकी आवश्यकता है, और इस बारे में स्पष्टीकरण की आवश्यकता नहीं है)। टिम पीटर्स (क्लैप पोस्ट 2002-12-22)

यह कहने के बाद कि, मैं (समय-समय पर) मेटाक्लासेस के सही उपयोगों में चलता हूं। जो मन में आता है वह Django में होता है जहां आपके सभी मॉडल मॉडल से विरासत में मिलते हैं। मॉडल। मॉडेल, बदले में, अपने डीबी मॉडल को Django के ORM अच्छाई के साथ लपेटने के लिए कुछ गंभीर जादू करता है। यह जादू मेटाक्लासेस के माध्यम से होता है। यह सभी प्रकार के अपवाद वर्गों, प्रबंधक वर्गों आदि का निर्माण करता है।

कहानी की शुरुआत के लिए django / db / मॉडल / base.py, class ModelBase () देखें।


खैर, हां, मैं बात देख रहा हूं। मुझे आश्चर्य नहीं है कि "कैसे" या "क्यों" मेटाक्लासेस का उपयोग करने के लिए, मुझे आश्चर्य है कि "कौन" और "क्या"। ओआरएम एक सामान्य मामला है जिसे मैं देख रहा हूं। दुर्भाग्य से Django के ORM SQLAlchemy की तुलना में बहुत गरीब है जिसमें कम जादू है। जादू बुरा है, और मेटाक्लासेस वास्तव में इसके लिए आवश्यक नहीं हैं।
अली अफसर

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

6

पायथन में डोमेन स्पेसिफिक लैंग्वेज के निर्माण के लिए मेटाक्लासेस आसान हो सकता है। ठोस उदाहरण Django, SQLObject के डेटाबेस स्कीमाटा के घोषणात्मक वाक्यविन्यास हैं।

इयान बीकिंग द्वारा ए कंजर्वेटिव मेटाक्लास का एक मूल उदाहरण :

मैंने जिन मेटाक्लस का उपयोग किया है, वे मुख्य रूप से प्रोग्रामिंग की घोषित शैली की सहायता के लिए हैं। उदाहरण के लिए, एक सत्यापन स्कीमा पर विचार करें:

class Registration(schema.Schema):
    first_name = validators.String(notEmpty=True)
    last_name = validators.String(notEmpty=True)
    mi = validators.MaxLength(1)
    class Numbers(foreach.ForEach):
        class Number(schema.Schema):
            type = validators.OneOf(['home', 'work'])
            phone_number = validators.PhoneNumber()

कुछ अन्य तकनीकें: पाइथन (पीडीएफ) में एक डीएसएल के निर्माण के लिए सामग्री

संपादित करें (अली द्वारा): संग्रह और उदाहरणों का उपयोग करके ऐसा करने का एक उदाहरण है जो मैं पसंद करूंगा। महत्वपूर्ण तथ्य ऐसे उदाहरण हैं, जो आपको अधिक शक्ति देते हैं, और मेटाक्लासेस का उपयोग करने के कारण को समाप्त करते हैं। इसके अलावा ध्यान देने योग्य बात यह है कि आपका उदाहरण कक्षाओं और उदाहरणों के मिश्रण का उपयोग करता है, जो निश्चित रूप से एक संकेत है कि आप यह सब मेटाक्लस के साथ नहीं कर सकते हैं। और वास्तव में इसे करने का गैर-समान तरीका बनाता है।

number_validator = [
    v.OneOf('type', ['home', 'work']),
    v.PhoneNumber('phone_number'),
]

validators = [
    v.String('first_name', notEmpty=True),
    v.String('last_name', notEmpty=True),
    v.MaxLength('mi', 1),
    v.ForEach([number_validator,])
]

यह सही नहीं है, लेकिन पहले से ही लगभग शून्य जादू है, मेटाक्लासेस की कोई आवश्यकता नहीं है, और एकरूपता में सुधार हुआ है।


इसके लिए धन्यवाद। यह मेरे द्वारा उपयोग किए जाने वाले उपयोग-मामले का एक बहुत अच्छा उदाहरण है, जो अनावश्यक, बदसूरत और असहनीय है, जो सरल संग्रह उदाहरण (आवश्यकता के अनुसार नेस्टेड संग्रह के साथ) के आधार पर सरल होगा।
अली अफसर

1
@ एली ए: मेटाकालेज़ के माध्यम से घोषणात्मक वाक्यविन्यास और सरल संग्रह उदाहरण के आधार पर एक दृष्टिकोण के बीच साइड-बाय-साइड तुलना का एक ठोस उदाहरण प्रदान करने के लिए आपका स्वागत है।
jfs

@ एली ए: संग्रह शैली का उदाहरण जोड़ने के लिए आप मेरे उत्तर को संपादित कर सकते हैं।
jfs

ठीक है कि किया क्षमा करें आज थोड़ी जल्दी में हैं, लेकिन बाद में / कल किसी भी प्रश्न का उत्तर देने का प्रयास करेंगे। छुट्टियां आनंददायक हों!
अली अफसर

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

6

मेटाक्लास के उपयोग का एक उचित पैटर्न एक बार कुछ ऐसा कर रहा है जब एक वर्ग को जब भी एक ही वर्ग का तात्कालिक रूप से बार-बार परिभाषित किया जाता है।

जब कई वर्ग एक ही विशेष व्यवहार साझा करते हैं, __metaclass__=Xतो स्पष्ट रूप से विशेष उद्देश्य कोड को दोहराने और / या तदर्थ साझा किए गए सुपरक्लेसेस को शुरू करने से बेहतर होता है।

लेकिन यहां तक ​​कि केवल एक विशेष वर्ग और कोई पूर्वाभासपूर्ण विस्तार के साथ, __new__और __init__मेटाक्लास विशेष उद्देश्य कोड और सामान्य defऔर classवर्ग परिभाषा शरीर में बयानों की तुलना में वर्ग चर या अन्य वैश्विक डेटा को आरंभ करने के लिए एक क्लीनर तरीका है ।


5

जब मैंने पायथन में मेटाक्लासेस का उपयोग किया था, तब केवल फ़्लिकर एपीआई के लिए एक आवरण लिखा था।

मेरा लक्ष्य फ़्लिकर की एपी साइट को परिमार्जन करना था और गतिशील रूप से पायथन ऑब्जेक्ट्स का उपयोग करके एपीआई एक्सेस की अनुमति देने के लिए एक पूर्ण श्रेणी पदानुक्रम उत्पन्न करना था :

# Both the photo type and the flickr.photos.search API method 
# are generated at "run-time"
for photo in flickr.photos.search(text=balloons):
    print photo.description

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


2
आप मेटाक्लस का उपयोग किए बिना गतिशील रूप से प्रकार उत्पन्न कर सकते हैं। >>> मदद (प्रकार)
अली अफसर

8
यहां तक ​​कि अगर आप इसके बारे में पता नहीं कर रहे हैं , तब आप मेटाक्लासेस का उपयोग कर रहे हैं । प्रकार एक मेटाक्लस है, वास्तव में सबसे आम है। :-)
विक्की

5

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

मैं डिबगिंग के लिए उनके उपयोग को देख सकता हूं, अमीर जानकारी प्राप्त करने के लिए अपने सभी बेस कक्षाओं में मेटाक्लस जोड़ सकता हूं। मैं कुछ बॉयलरप्लेट कोड (लेकिन स्पष्टता के नुकसान पर) से छुटकारा पाने के लिए केवल (बहुत) बड़ी परियोजनाओं में उनका उपयोग देखता हूं। उदाहरण के लिए sqlalchemy उनका उपयोग कहीं और करता है, अपनी कक्षा परिभाषा में एक विशेषता मान के आधार पर सभी उपवर्गों में एक विशेष कस्टम विधि जोड़ने के लिए जैसे कि एक खिलौना उदाहरण

class test(baseclass_with_metaclass):
    method_maker_value = "hello"

एक मेटाक्लस हो सकता है जो उस वर्ग में "हैलो" के आधार पर विशेष गुणों के साथ एक विधि उत्पन्न करता है (एक विधि जो एक स्ट्रिंग के अंत में "हैलो" जोड़ा गया है)। यह सुनिश्चित करने के लिए स्थिरता के लिए अच्छा हो सकता है कि आपको अपने द्वारा बनाए गए प्रत्येक उपवर्ग में एक विधि लिखने की ज़रूरत नहीं है, इसके बजाय आपको यह निर्धारित करना होगा कि method_maker_value है।

इसके लिए इसकी आवश्यकता बहुत कम है, और केवल कुछ टाइपिंग में कटौती करता है, जब तक कि आपके पास पर्याप्त पर्याप्त कोडबेस न हो, तब तक यह वास्तव में विचार करने योग्य नहीं है।


5

आपको कभी भी मेटाक्लस का उपयोग करने की आवश्यकता नहीं है , क्योंकि आप हमेशा एक वर्ग का निर्माण कर सकते हैं जो वह करता है जो आप उस श्रेणी के एकीकरण या एकत्रीकरण का उपयोग करना चाहते हैं जिसे आप संशोधित करना चाहते हैं।

उस ने कहा, यह स्मॉलटॉक और रूबी में एक मौजूदा वर्ग को संशोधित करने में सक्षम होने के लिए बहुत आसान हो सकता है, लेकिन पायथन सीधे ऐसा करना पसंद नहीं करता है।

पायथन में मेटाक्ललिंग पर एक उत्कृष्ट DeveloperWorks लेख है जो मदद कर सकता है। विकिपीडिया लेख भी काफ़ी अच्छी है।


1
ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग करने के लिए आपको वस्तुओं की भी आवश्यकता नहीं है - आप इसे प्रथम श्रेणी के कार्यों के साथ कर सकते हैं। इसलिए आपको वस्तुओं का उपयोग करने की आवश्यकता नहीं है । लेकिन वे सुविधा के लिए वहाँ हैं। इसलिए मुझे यकीन नहीं है कि आप पहले पैराग्राफ में कौन सा बिंदु बनाने की कोशिश कर रहे हैं।
टायलर क्रॉम्पटन

1
प्रश्न पर वापस देखें।
चार्ली मार्टिन

4

कुछ GUI लाइब्रेरीज़ को परेशानी होती है जब कई थ्रेड्स उनके साथ इंटरैक्ट करने की कोशिश करते हैं। tkinterऐसा ही एक उदाहरण है; और जब कोई स्पष्ट रूप से घटनाओं और कतारों के साथ समस्या को संभाल सकता है, तो पुस्तकालय का इस तरह से उपयोग करना कहीं अधिक सरल हो सकता है जो समस्या को पूरी तरह से नजरअंदाज कर दे। निहारना - metaclasses का जादू।

एक पूरे पुस्तकालय को गतिशील रूप से गतिशील रूप से फिर से लिखने में सक्षम होने के कारण यह एक बहुपरत अनुप्रयोग में अपेक्षित रूप से ठीक से काम करता है, कुछ परिस्थितियों में बेहद मददगार हो सकता है। Safetkinter मॉड्यूल है कि द्वारा प्रदान की एक metaclass की मदद से threadbox मॉड्यूल - घटनाओं और कतारों की जरूरत नहीं।

इसका एक साफ पहलू threadboxयह है कि यह परवाह नहीं करता है कि यह किस वर्ग को क्लोन करता है। यह एक उदाहरण प्रदान करता है कि कैसे सभी बेस कक्षाओं को जरूरत पड़ने पर मेटाक्लस द्वारा छुआ जा सकता है। मेटाक्लासेस के साथ आने वाला एक और लाभ यह है कि वे विरासत में मिली कक्षाएं भी चलाते हैं। कार्यक्रम जो खुद लिखते हैं - क्यों नहीं?


4

एक मेटाक्लस का एकमात्र वैध उपयोग-मामला अन्य नोसी डेवलपर्स को आपके कोड को छूने से रोकना है। एक बार एक नासमझ डेवलपर ने मेटाक्लेसेस को मास्ट कर दिया और आपके साथ घूमना शुरू कर दिया, उन्हें बाहर रखने के लिए दूसरे स्तर या दो में फेंक दें। यदि वह काम नहीं करता है, तो type.__new__एक पुनरावर्ती मेटाक्लास का उपयोग करके या शायद कुछ योजना का उपयोग करना शुरू करें ।

(गाल में लिखित जीभ, लेकिन मैंने इस तरह का मोटापा देखा है। Django एक आदर्श उदाहरण है)


7
मुझे यकीन नहीं है कि प्रेरणा Django में समान थी।
अली अफशर

3

Metaclasses प्रोग्रामिंग की जगह नहीं ले रहे हैं! वे बस एक चाल है जो कुछ कार्यों को स्वचालित या अधिक सुरुचिपूर्ण बना सकते हैं। इसका एक अच्छा उदाहरण है पाइलेशन सिंटैक्स हाइलाइटिंग लाइब्रेरी। इसका एक वर्ग है जिसे बुलाया जाता हैRegexLexer होता है, जो उपयोगकर्ता को एक वर्ग पर नियमित अभिव्यक्ति के रूप में लेक्सिंग नियमों के एक सेट को परिभाषित करने देता है। एक उपयोगी पार्सर में परिभाषाओं को चालू करने के लिए एक मेटाक्लस का उपयोग किया जाता है।

वे नमक की तरह हैं; इसका उपयोग करना बहुत आसान है।


खैर, मेरी राय में, कि Py Py का मामला सिर्फ अनावश्यक है। सिर्फ एक तानाशाह की तरह एक सादा संग्रह क्यों नहीं है, एक वर्ग को ऐसा करने के लिए क्यों मजबूर करें?
अली अफसर

4
क्योंकि एक वर्ग अच्छा लेक्सर के विचार को समझता है और अन्य उपयोगी तरीके जैसे अनुमान_फिलनेम (), इत्यादि
बेंजामिन पीटरसन

3

जिस तरह से मैंने मेटाक्लासेस का उपयोग किया वह कक्षाओं के लिए कुछ विशेषताएँ प्रदान करना था। उदाहरण के लिए:

class NameClass(type):
    def __init__(cls, *args, **kwargs):
       type.__init__(cls, *args, **kwargs)
       cls.name = cls.__name__

नाम विशेषता को हर वर्ग पर डाल देगा, जिसमें मेटाक्लास को NameClass को इंगित करने के लिए सेट किया जाएगा।


5
हां, यह काम करता है। आप एक सुपरक्लास का भी उपयोग कर सकते हैं, जो कोड में कम से कम स्पष्ट और अनुसरण करने योग्य है। ब्याज से बाहर, आपने इसके लिए क्या उपयोग किया?
अली अफसर

2

यह एक मामूली उपयोग है, लेकिन ... एक चीज जो मैंने मेटाक्लासेस के लिए उपयोगी पाई है, वह है जब भी कोई उपवर्ग बनाया जाता है तो एक फ़ंक्शन को लागू करना। मैंने इसे एक मेटाक्लस में संहिताबद्ध किया जो एक __initsubclass__विशेषता की तलाश में है: जब भी कोई उपवर्ग बनाया जाता है, तो सभी अभिभावक वर्ग जो उस पद्धति को परिभाषित करते हैं, के साथ लागू होते हैं __initsubclass__(cls, subcls)। यह एक अभिभावक वर्ग के निर्माण की अनुमति देता है, जो तब कुछ वैश्विक रजिस्ट्री के साथ सभी उपवर्गों को पंजीकृत करता है, जब भी परिभाषित किया जाता है, तो उपवर्गों पर अनियंत्रित जांच चलाता है, देर से-बाध्यकारी संचालन करता है, आदि ... सभी को मैन्युअल रूप से फ़ंक्शन करने या कस्टम मेटाफ़्लासेस बनाने की आवश्यकता नहीं है। इन अलग-अलग कर्तव्यों का पालन करें।

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


1

मुझे हाल ही में http://canim.ire.org/data/bulkdata.html से अमेरिकी जनगणना डेटा के साथ आबादी वाले डेटाबेस तालिका के आसपास SQLAlchemy मॉडल को परिभाषित करने में मदद करने के लिए एक मेटाक्लस का उपयोग करना पड़ा।

IRE जनगणना डेटा तालिकाओं के लिए डेटाबेस शेल प्रदान करता है , जो जनगणना ब्यूरो के p012015, p012016, p012017, आदि के नामकरण सम्मेलन के बाद पूर्णांक कॉलम बनाते हैं।

मैं चाहता था कि a) एक model_instance.p012017सिंटैक्स का उपयोग करके इन कॉलमों को एक्सेस करने में सक्षम हो , b) मैं जो कर रहा था उसके बारे में स्पष्ट रूप से स्पष्ट हो और c) मॉडल पर दर्जनों फ़ील्ड्स को स्पष्ट रूप से परिभाषित नहीं करना है, इसलिए मैंने SQLAlchemy की DeclarativeMetaश्रेणी के माध्यम से इसे टाइप करने के लिए उप-वर्ग किया कॉलम और स्वचालित रूप से कॉलम के अनुरूप मॉडल फ़ील्ड बनाते हैं:

from sqlalchemy.ext.declarative.api import DeclarativeMeta

class CensusTableMeta(DeclarativeMeta):
    def __init__(cls, classname, bases, dict_):
        table = 'p012'
        for i in range(1, 49):
            fname = "%s%03d" % (table, i)
            dict_[fname] = Column(Integer)
            setattr(cls, fname, dict_[fname])

        super(CensusTableMeta, cls).__init__(classname, bases, dict_)

मैं तब अपने मॉडल परिभाषा के लिए इस मेटाक्लस का उपयोग कर सकता हूं और मॉडल पर स्वचालित रूप से प्रगणित फ़ील्ड तक पहुंच सकता हूं:

CensusTableBase = declarative_base(metaclass=CensusTableMeta)

class P12Tract(CensusTableBase):
    __tablename__ = 'ire_p12'

    geoid = Column(String(12), primary_key=True)

    @property
    def male_under_5(self):
        return self.p012003

    ...

1

यहां वर्णित एक वैध उपयोग प्रतीत होता है - मेटाक्लास के साथ पायथन डॉकस्ट्रिंग्स को फिर से लिखना।


0

मुझे बाइनरी पार्सर के लिए एक बार उनका उपयोग करना पड़ा ताकि इसका उपयोग करना आसान हो सके। आप तार पर मौजूद फ़ील्ड की विशेषताओं के साथ एक संदेश वर्ग को परिभाषित करते हैं। उन्हें उस तरह से आदेश देने की आवश्यकता थी जिस तरह से वे अंतिम तार प्रारूप का निर्माण करने के लिए घोषित किए गए थे। आप मेटाक्लासेस के साथ ऐसा कर सकते हैं, यदि आप एक ऑर्डर किए गए नाम स्थान का उपयोग करते हैं। वास्तव में, मेटाक्लासेस के लिए इसके उदाहरणों में:

https://docs.python.org/3/reference/datamodel.html#metaclass-example

लेकिन सामान्य तौर पर: बहुत सावधानी से मूल्यांकन करें, अगर आपको वास्तव में मेटाक्लिस की अतिरिक्त जटिलता की आवश्यकता है।


0

@Dan Gittik से जवाब अच्छा है

अंत में उदाहरण कई बातों को स्पष्ट कर सकते हैं, मैंने इसे अजगर 3 में बदल दिया और कुछ स्पष्टीकरण दिया:

class MetaMetaclass(type):
    def __new__(meta, name, bases, attrs):
        def __new__(meta, name, bases, attrs):
            cls = type.__new__(meta, name, bases, attrs)
            cls._label = 'Made in %s' % meta.__name__
            return cls

        attrs['__new__'] = __new__
        return type.__new__(meta, name, bases, attrs)

#China is metaclass and it's __new__ method would be changed by MetaMetaclass(metaclass)
class China(MetaMetaclass, metaclass=MetaMetaclass):
    __metaclass__ = MetaMetaclass

#Taiwan is metaclass and it's __new__ method would be changed by MetaMetaclass(metaclass)
class Taiwan(MetaMetaclass, metaclass=MetaMetaclass):
    __metaclass__ = MetaMetaclass

#A is a normal class and it's __new__ method would be changed by China(metaclass)
class A(metaclass=China):
    __metaclass__ = China

#B is a normal class and it's __new__ method would be changed by Taiwan(metaclass)
class B(metaclass=Taiwan):
    __metaclass__ = Taiwan


print(A._label)  # Made in China
print(B._label)  # Made in Taiwan
  • सब कुछ ऑब्जेक्ट है, इसलिए क्लास ऑब्जेक्ट है
  • क्लास ऑब्जेक्ट मेटाक्लास द्वारा बनाया गया है
  • सभी प्रकार से विरासत में मिला वर्ग मेटाक्लस है
  • मेटाक्लास वर्ग निर्माण को नियंत्रित कर सकता है
  • मेटाक्लास भी बनाने वाले मेटाक्लस को नियंत्रित कर सकता है (इसलिए यह हमेशा के लिए लूप कर सकता है)
  • इस मेटाप्रोग्रामिंग ... आप रनिंग टाइम पर टाइप सिस्टम को नियंत्रित कर सकते हैं
  • फिर से, सब कुछ वस्तु है, यह एक समान प्रणाली है, प्रकार बनाएँ प्रकार, और प्रकार बनाएँ उदाहरण

0

एक अन्य उपयोग मामला तब है जब आप वर्ग-स्तरीय विशेषताओं को संशोधित करने में सक्षम होना चाहते हैं और सुनिश्चित करें कि यह केवल ऑब्जेक्ट को हाथ में प्रभावित करता है। व्यवहार में, इसका तात्पर्य मेटाक्लासेस और क्लास इंस्टेंमेंट्स के चरणों को "विलय" करना है, इस प्रकार आप अपने स्वयं के (अद्वितीय) तरह के वर्ग उदाहरणों से निपटने के लिए अग्रणी हैं।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.