Grałem około z metaclasses w CPython 3.2.2 i zauważyłem, że jest możliwe, aby skończyć z klasy, która ma swój własny typ:Python - obiekt może być jego własnym typem?
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
Dla naszego metaklasą A
, tam naprawdę nie wydają się znacznie od rozróżnienia między klasą i przykład atrybutów:
>>> 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__`
Wszystko to działa tak samo (oprócz zmieniających się __metaclass__
i __next__
nie jest specjalna metoda) w CPython 2.7.2, 1.6.0 (pypy który implementuje Python 2.7.1) i Jython 2.2.1 (nie mam pojęcia, co Python wersja, która jest, jeśli w ogóle - nie bardzo znam Jython).
Nie mogę znaleźć wiele wyjaśnień na temat warunków, w których przyznanie __class__
jest dozwolone (najwyraźniej typy te muszą być zdefiniowane przez użytkownika i mają podobny układ w pewnym sensie?). Zauważ, że A
musi być zarówno podklasą, jak i instancją MC
, aby zadanie zadziałało na __class__
. Czy tak naprawdę rekurencyjne hierarchie metaklasu powinny być akceptowalne? Jestem bardzo zmieszany.
Dokument, który dużo wyjaśnia o typach Pythona, jest następujący: http://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html Powinien to wyjaśnić, choć wydaje się, że nie omawia tej sytuacji. –