2013-01-07 36 views
10

मैं क्यों निम्नलिखित कोड एक खास तरह से है, जो नीचे वर्णित है बर्ताव करता है समझ में नहीं कर सकते हैं:अजगर विरासत, metaclasses और प्रकार() फ़ंक्शन

from abc import ABCMeta 

class PackageClass(object): 
    __metaclass__ = ABCMeta   

class MyClass1(PackageClass): 
    pass 

MyClass2 = type('MyClass2', (PackageClass,), {}) 

print MyClass1 
print MyClass2 

>>> <class '__main__.MyClass1'> 
>>> <class 'abc.MyClass2'> 

क्यों repr(MyClass2) कहते abc.MyClass2 (जो रास्ता नहीं कर रहा है सच)? धन्यवाद!

+2

परियोजना संरचना यहां पूरी तरह से अप्रासंगिक प्रतीत होती है। मैं उस भाग को हटाने की सलाह दूंगा और बस इसे 1 मॉड्यूल के रूप में रखूंगा (वर्णित व्यवहार अभी भी वहां है)। – mgilson

+0

@mgilson ध्यान देने के लिए धन्यवाद, अद्यतन किया गया। –

+1

और, एक साइड नोट के रूप में, यह व्यवहार अभी भी python3.x में है (मैंने अभी इसका परीक्षण किया है) – mgilson

उत्तर

6

समस्या इस तथ्य से उत्पन्न होती है कि ABCMeta__new__ ओवरराइड करता है और इसके सुपरक्लास कन्स्ट्रक्टर (type()) को कॉल करता है। type() ने अपनी कॉलिंग संदर्भ से नई कक्षा के लिए __module__ प्राप्त किया है; इस मामले में, type कॉल abc मॉड्यूल से आता है। इसलिए, नई कक्षा में __module__abc पर सेट है (type() के बाद से यह जानने का कोई तरीका नहीं है कि वास्तविक वर्ग निर्माण __main__ में हुआ था)।

आसान तरीका चारों ओर सिर्फ __module__ खुद के प्रकार बनाने के बाद स्थापित करने के लिए है:

MyClass2 = type('MyClass2', (PackageClass,), {}) 
MyClass2.__module__ = __name__ 

मैं भी एक बग रिपोर्ट दायर करने की सिफारिश करेंगे।

संबंधित: Base metaclass overriding __new__ generates classes with a wrong __module__, Weird inheritance with metaclasses

1: type एक प्रकार वस्तु सी इसकी में परिभाषित new method मौजूदा वैश्विक __name____module__ के रूप में, जब तक यह एक metaclass निर्माता कॉल का उपयोग करता है।

+0

इस तरह के विस्तृत उत्तर के लिए धन्यवाद, @nneonneo! –