2012-06-07 57 views
12

我玩弄元类在CPython的3.2.2,和我注意到它是可能的一个类,它是它自己的类型结束:Python - 一个对象可以是它自己的类型?

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 

对于我们的元类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,1.6.0 PyPy(它实现了Python 2.7.1)和Jython 2.2.1(不知道Python是什么版本,如果有的话 - 我对Jython不是很熟悉)。

对于允许指定__class__的条件,我找不到很多解释(显然有关类型必须是用户定义的,并且在某种意义上具有相似的布局?)。请注意,A必须是MC的子类和实例,才能使__class__正常工作。像这样的递归元类层次真的应该是可以接受的吗?我很困惑。

+1

一个解释了很多关于Python类型的文档如下:http://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html它应该清除一些东西,尽管它似乎没有讨论这种情况。 –

回答

6

递归元类hierachies实际上是语言核心的一部分:

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

因此,即使标准的元类type是其自己的类型。这个构造没有概念上的问题 - 它只是意味着类的__class__属性指向类本身。

__class__属性的赋值只允许用户定义的类。如果原始类别和新类别都没有定义__slots__,或者两者都将__slots__设置为相同的顺序,则分配是合法的。

相关问题