【问题标题】:Python - an object can be its own type?Python - 一个对象可以是它自己的类型?
【发布时间】:2012-06-11 18:17:25
【问题描述】:

我在 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)和 Jython 2.2 中都一样(除了更改为 __metaclass____next__ 不是特殊方法)。 1(不知道是什么 Python 版本,如果有的话 - 我对 Jython 不是很熟悉)。

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

【问题讨论】:

标签: python class recursion metaclass


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2011-09-25
    • 2017-04-22
    • 1970-01-01
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    • 2016-12-28
    相关资源
    最近更新 更多