2011-10-31 14 views
5

उत्कृष्ट SO post पढ़ने के बाद, मैं एक मॉड्यूल स्तर metaclass क्राफ्टिंग की कोशिश की:अजगर metaclass और वस्तु आधार वर्ग

def metaclass(future_class_name, future_class_parents, future_class_attrs): 
    print "module.__metaclass__" 
    future_class_attrs["bar"]="bar" 
    return type(future_class_name, future_class_parents, future_class_attrs) 

__metaclass__=metaclass 


class Foo(object): 

    def __init__(self): 
     print 'Foo.__init__' 

f=Foo() 

यह काम नहीं करता (यानी "। मॉड्यूल metaclass" मुद्रित नहीं प्राप्त करता है) जब तक मैं फू के object बेस क्लास को हटा नहीं देता। कैसे?

नोट: मैं पायथन 2.6.1 का उपयोग कर रहा हूं।

उत्तर

3

ऑब्जेक्ट से विरासत स्वचालित रूप से मेटाक्लास को इसके साथ लाता है। यह आपके मॉड्यूल स्तर __metaclass__ विनिर्देश को ओवरराइड करता है।

metaclass श्रेणी स्तर पर निर्दिष्ट किया जाता है, तो वस्तु ओवरराइड नहीं होगा:

def metaclass(future_class_name, future_class_parents, future_class_attrs): 
    print "module.__metaclass__" 
    future_class_attrs["bar"]="bar" 
    return type(future_class_name, future_class_parents, future_class_attrs) 

class Foo(object): 
    __metaclass__ = metaclass 

    def __init__(self): 
     print 'Foo.__init__' 

f=Foo() 

http://docs.python.org/reference/datamodel.html?highlight=metaclass#customizing-class-creation

+0

विनिर्देशन ऐसी कोई बात नहीं कहता है। यह क्या कहता है कि यदि बेसक्लस है, तो बेसक्लास का मेटाक्लास इस्तेमाल किया जाएगा, भले ही बेसक्लास मेटाक्लास निर्दिष्ट करता हो या नहीं। – Marcin

2

देखें विनिर्देश specifies the order in which Python will look for a metaclass:

उचित metaclass निम्नलिखित प्राथमिकता नियमों द्वारा निर्धारित किया गया है:

  • यदि dict['__metaclass__'] मौजूद है, तो इसका उपयोग किया जाता है।
  • अन्यथा, यदि कम से कम एक बेस क्लास है, तो इसका मेटाक्लास उपयोग किया जाता है (यह __class__ विशेषता पहले और यदि नहीं मिला, तो इसका प्रकार उपयोग करता है)।
  • अन्यथा, यदि __metaclass__ नामक वैश्विक चर मौजूद है, तो इसका उपयोग किया जाता है।
  • अन्यथा, पुरानी शैली, क्लासिक मेटाक्लास (types.ClassType) का उपयोग किया जाता है।

आप (जो भी आधार वर्ग है तो भी यह अंततः object से विरासत नहीं है) सबसे बढ़कर पर एक आधार वर्ग होने से देखेंगे पूर्व empts मॉड्यूल स्तरीय __metaclass__

संबंधित मुद्दे