2012-06-07 5 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__ в той же последовательности.

Смежные вопросы