[Python]: metaclass memo ======================== 全くよく解らないので、ソースを見てみる http://www-06.ibm.com/jp/developerworks/linux/030425/j_l-pymeta.html Versionは2.5.1 http://svn.python.org/view/python/tags/r251/ から落としてくる `__metaclass__` でgrepすると - Modules/_ctypes/_ctypes.c - Python/ceval.c などが見つかる **Python/ceval.c:4060** .. sourcecode:: c static PyObject * build_class(PyObject *methods, PyObject *bases, PyObject *name) { `build_class` はPythonバイトコード命令の `BUILD_CLASS` に対応している http://www.python.jp/doc/2.4/lib/bytecodes.html BUILD_CLASS 新しいクラスオブジェクトを作成します。TOSはメソッド辞書、TOS1は基底クラスの名前のタプル、TOS2はクラス名です。 .. sourcecode:: c PyObject *metaclass = NULL, *result, *base; if (PyDict_Check(methods)) metaclass = PyDict_GetItemString(methods, "__metaclass__"); if (metaclass != NULL) Py_INCREF(metaclass); else if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) { base = PyTuple_GET_ITEM(bases, 0); metaclass = PyObject_GetAttrString(base, "__class__"); if (metaclass == NULL) { PyErr_Clear(); metaclass = (PyObject *)base->ob_type; Py_INCREF(metaclass); } } else { PyObject *g = PyEval_GetGlobals(); if (g != NULL && PyDict_Check(g)) metaclass = PyDict_GetItemString(g, "__metaclass__"); if (metaclass == NULL) metaclass = (PyObject *) &PyClass_Type; Py_INCREF(metaclass); } result = PyObject_CallFunctionObjArgs(metaclass, name, bases, methods, NULL); Py_DECREF(metaclass); if (result == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) { ... } return result; } `metaclass` は #. クラスの `__metaclass__` を代入 #. スーパークラス( `__bases__` )がある 1つ目のスパークラスの `__class__` を代入 なければ、1つ目のスパークラスの `ob_type` を代入 #. Global(module)の `__metaclass__` を代入 #. PyClass_Type を代入 が入る。 `__metaclass__` を記述するということは、このステップを操作すること。 Py_INCREF, Py_DECREF は参照カウンタのインクリメント/デクリメント。 http://www.python.jp/doc/2.4/ext/refcountsInPython.html ob_type ~~~~~~~ http://www.python.jp/doc/2.4/api/type-structs.html PyTypeObject* ob_type 型自体の型、別の言い方をするとメタタイプです。 PyObject_HEAD_INIT マクロで初期化され、通常は &PyType_Type になります。 Python 2.2.1 およびそれ以降では基底クラスの ob_type フィールドに初期化します。 ob_type が非ゼロの場合、PyType_Ready() は このフィールドを変更しません。 2.2.1 と 2.3 以降では、サブタイプはこのフィールドを継承します。 PyClass_Type ~~~~~~~~~~~~ **Objects/classobject.c:423** .. sourcecode:: c PyTypeObject PyClass_Type = { PyObject_HEAD_INIT(&PyType_Type) ... }; PyObject_HEAD_INIT ~~~~~~~~~~~~~~~~~~ http://www.python.jp/doc/2.4/ext/dnt-basics.html PyObject_HEAD_INIT(&PyType_Type) この場合、タイプオブジェクトの型は「type」という名前になります ---- http://MiCHiLU.com/blog/posts/129/ - Added at Fri, 18 Jan 2008 01:12:35 +0900 - Last modified at Fri, 18 Jan 2008 01:18:52 +0900 This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.1 Japan License. http://creativecommons.org/licenses/by-nc-sa/2.1/jp/