4

Python のすべてがオブジェクトであり、これらのオブジェクトの「タイプ」(またはクラス) が「タイプ」であることを理解しています。それに型の型も型そのもの。(ここでうまく説明されているように)

私が理解していないのは、この循環参照がどのように実装されているかです。だから私はここを見ました。私が探しているものを説明するかもしれない部分を引用するには:

PyTypeObject* PyObject.ob_type

これはタイプのタイプ、つまりそのメタタイプです。これは PyObject_HEAD_INIT マクロへの引数によって初期化され、その値は通常 &PyType_Type になります。ただし、(少なくとも) Windows で使用可能でなければならない動的にロード可能な拡張モジュールの場合、コンパイラはこれが有効な初期化子ではないと文句を言います。したがって、規則では、PyObject_HEAD_INIT マクロに NULL を渡し、モジュールの初期化関数の開始時にこのフィールドを明示的に初期化してから、他の処理を実行します。これは通常、次のように行われます。

Foo_Type.ob_type = &PyType_Type;

C は OOP ベースではないため、クラスを作成するときに、オブジェクト自体を独自のクラスとして指す属性を持つことができることを理解しています。ここでの私の理解不足が私を混乱状態に陥らせたと確信しています.これが他のスクリプト言語の設計における通常の慣行なのか、それともある種のパターンなのかを誰か指摘できますか?誰かがこれに光を当てることができれば.私はそれに感謝します。

編集:ここで次のことがわかりました:

PyObject* PyType_Type

これは型オブジェクトの型オブジェクトです。Python レイヤーの type および types.TypeType と同じオブジェクトです。

それはどうですか?

4

1 に答える 1

4

PyType_Type.ob_type = &PyType_Type を定義するコードには、いくつかの間接化が含まれます。_Py_ReadyTypes()を呼び出すと、すべてが関数内で開始されますPyType_Ready(&PyType_Type)。関数が呼び出される前は、メンバーtp_baseob_typeは両方ともNULLです。この関数は最初type->tp_base&PyBaseObject_Type( objectPython 空間にある) に設定し、次に に設定しますtype->ob_type = PyBaseObject_Type.ob_type。コードではPy_TYPE()、これは単なるマクロですob->ob_type。オブジェクトの型は type であるため、コードは type の型を type に設定します。

これで次のことができます。

>>> type.__bases__
(<class 'object'>,)
>>> type(object)
<class 'type'>
>>> type(type(object))
<class 'type'>

この定義は、type を object のインスタンスに加えてそれ自体にし、object を type のインスタンスにします。

>>> isinstance(type, object)
True
>>> isinstance(object, type)
True
>>> isinstance(type, type)
True

型の初期化コードは、Python 疑似コードで理解するのがはるかに簡単です。

# object's class is type
object.__class__ = type
# PyType_Ready(type) sets:
type.__bases__ = (object,)
type.__class__ = type(object)
于 2013-09-09T21:16:12.237 に答える