Python - 一个对象可以是它自己的类型吗?

时间:2012-06-07 16:41:08

标签: python class recursion metaclass

我在CPython 3.2.2中玩过元类,我注意到最终可能会有一个类型的类:

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__`

所有这些在CPython 2.7.2,PyPy 1.6.0(实现Python 2.7.1)中的工作原理相同(除了更改为__metaclass____next__不是特殊方法),和Jython 2.2.1(不知道是什么Python版本,如果有的话 - 我对Jython不是很熟悉)。

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

1 个答案:

答案 0 :(得分:6)

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

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

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

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