12

私はCPython3.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.1(Pythonのバージョンが何であるかわからない)でも同じように機能します(に変更し__metaclass__、特別なメソッドではありません)。 __next__、もしあれば-私はJythonにあまり精通していません)。

割り当てが許可される条件について多くの説明を見つけることができません__class__(明らかに、関係するタイプはユーザー定義であり、ある意味で同様のレイアウトを持っている必要がありますか?)。割り当てが機能するAには、サブクラスとのインスタンスの両方である必要があることに注意してください。このような再帰的なメタクラス階層は本当に受け入れられるはずですか?私はとても混乱しています。MC__class__

4

1 に答える 1

6

再帰的なメタクラス階層は、実際には言語コアの一部です。

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

したがって、標準のメタクラスでさえtype独自のタイプです。この構成には概念上の問題はありません。これ__class__は、クラスの属性がクラス自体を指していることを意味します。

属性への割り当ては__class__、ユーザー定義のクラスに対してのみ許可されます。__slots__元のクラスと新しいクラスの両方が定義されていない場合、または両方__slots__が同じシーケンスに設定されている場合、割り当ては有効です。

于 2012-06-07T21:01:28.567 に答える