2011-09-20 12 views
5

मैं एक metaclass मिला कहो ProductClass का __init__ ट्रिगर हुआ? बस मेटा के __call__ की वजह से?Metaclass के "__call__" और उत्पाद श्रेणी के "__init__"

अद्यतन:

अब, मैं ProductClass के लिए __new__ जोड़ें:

class ProductClass(object): 
     __metaclass__ = Meta 
     def __new__(cls, *args): 
      print "ProductClass: __new__ with", args 
      return super(ProductClass, cls).__new__(cls, *args) 
     def __init__(self, *args): 
      print "ProductClass: __init__ with", args 

p = ProductClass(1) 

यह मेटा के __call__ की कॉल करने के लिए जिम्मेदारी है ProductClass के __new__ और __init__?

उत्तर

4

हां - यह पर ProductClass.__init__ (या जैसा भी मामला हो) पर कॉल करने के लिए है। जब वर्ग कहा जाता है

उदाहरण के लिए metaclass में एक कस्टम __call__() विधि को परिभाषित करने की अनुमति देता है कस्टम व्यवहार, उदहारण के लिए:

documentation के शब्दों में हमेशा एक नया उदाहरण बनाने के लिए नहीं।

कि पेज भी एक परिदृश्य में जहाँ metaclass के __call__ एक अलग वर्ग का एक उदाहरण वापस आ सकते हैं उल्लेख है (अर्थात नहीं ProductClass अपने उदाहरण में)। इस परिदृश्य में यह स्वचालित रूप से ProductClass.__init__ पर कॉल करने के लिए अनुचित होगा।

+0

क्या हुआ यदि मैं "__new__" ProductClass में मिल गया? मेटा का "__call__" कॉल क्लाउड क्लास का "__new__" और "__init__" होगा? मेरा अद्यतन देखें। – Alcott

+0

और स्पष्ट रूप से, मेटा के "__call__" को उत्पाद क्लास के "__new__" से पहले पहले कहा जाता है। – Alcott

+0

समस्या यह है कि 'ProductClass .__ new__' और 'ProductClass .__ init__' को कॉल करने के लिए' मेटा .__ कॉल__' आवश्यक है। आम तौर पर, 'टाइप .__ call__' यह आपके लिए करता है, लेकिन जब आप' मेटा .__ कॉल__ 'को परिभाषित करते हैं, तो आप उस व्यवहार को _override_ करते हैं, जिसका अर्थ यह है कि जब तक आप ऐसा नहीं करते हैं तब तक निष्पादित नहीं किया जाता है। इसलिए, आपको या तो '__new__' और' __init__' को कॉल करने की आवश्यकता है, या 'टाइप .__ कॉल __ (cls, * args) जैसे किसी चीज़ पर कॉल करें। –

6

वहाँ एक विधि का विस्तार और यह अधिभावी, क्या तुम सिर्फ अधिभावी कहा जाता है, क्योंकि आप अपने __call__ विधि परिभाषित और आप माता-पिता __call__ फोन नहीं किया अपने metaclass Meta में किया था के बीच OOP में एक अंतर है। व्यवहार है कि आप माता-पिता विधि को फोन करके चाहते हैं आप __call__ विधि का विस्तार करने के लिए है के लिए:

class Meta(type): 
    def __call__(cls, *args): 
     print "Meta: __call__ with", args 
     return super(Meta, cls).__call__(*args) 
संबंधित मुद्दे