2012-06-07 16 views
12

मैं CPython 3.2.2 में metaclasses के साथ चारों ओर खेल रहा था, और मैंने देखा कि यह एक वर्ग है कि अपने स्वयं के प्रकार है के साथ खत्म करना संभव है:पायथन - एक वस्तु अपना प्रकार का हो सकता है?

Python 3.2.2 (default, Sep 5 2011, 21:17:14) 
[GCC 4.6.1] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> class MC(type):   #a boring metaclass that works the same as type 
...  pass 
... 
>>> class A(MC, metaclass=MC): #A is now both a subclass and an instance of MC... 
...  pass 
... 
>>> A.__class__ = A   #...and now A is an instance of itself? 
>>> A is type(A) 
True 

हमारे metaclass A के लिए, वहाँ वास्तव में नहीं लगता है वर्ग और उदाहरण के बीच एक अंतर के अधिक होने के लिए जिम्मेदार बताते हैं:

>>> A.__next__ = lambda self: 1 
>>> next(A) 
1          #special method lookup works correctly 
>>> A.__dict__ 
dict_proxy({'__module__': '__main__', 
'__next__': <function <lambda> at 0x17c9628>, 
'__doc__': None}) 
>>> type(A).__dict__ 
dict_proxy({'__module__': '__main__', 
'__next__': <function <lambda> at 0x17c9628>, 
'__doc__': None})        #they have the same `__dict__` 

यह एक ही काम करता है सभी (अलग __metaclass__ को परिवर्तित करने से, और __next__ एक विशेष विधि नहीं किया जा रहा) CPython 2.7.2, PyPy 1.6.0 (में जो पायथन 2.7.1 लागू करता है), और ज्योथन 2.2.1 (कोई विचार नहीं कि पाइथन क्या है संस्करण जो है, यदि कोई है - मैं ज्योथन से बहुत परिचित नहीं हूं)।

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

>>> type(type) 
<class 'type'> 

तो भी मानक metaclass type अपना अलग प्रकार है:

+1

एक दस्तावेज़ जो पाइथन प्रकारों के बारे में बहुत कुछ बताता है वह निम्न है: http://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html इसे चीजों को साफ़ करना चाहिए, हालांकि यह इस स्थिति पर चर्चा नहीं कर रहा है। –

उत्तर

6

रिकर्सिव metaclass hierachies वास्तव में भाषा कोर का हिस्सा हैं। इस निर्माण के साथ कोई वैचारिक समस्या नहीं है - इसका मतलब कक्षा वर्ग के वर्ग अंक की __class__ विशेषता है।

__class__ विशेषता के लिए असाइनमेंट केवल उपयोगकर्ता परिभाषित कक्षाओं के लिए अनुमति है। असाइनमेंट कानूनी है यदि मूल वर्ग और नई कक्षा दोनों __slots__ परिभाषित नहीं करते हैं, या दोनों समान अनुक्रम में __slots__ सेट करते हैं।

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