python class的创建

时间:2021-02-03 01:42:45
def f():
class a():
a=5
def f2():
pass Disassembly of f:
14 0 LOAD_CONST 1 ('a')
3 LOAD_CONST 3 (())
6 LOAD_CONST 2 (<code object a at 0133DB18, file "<module1>", line 14>)
9 MAKE_FUNCTION 0
12 CALL_FUNCTION 0
15 BUILD_CLASS
16 STORE_FAST 0 (a)
19 LOAD_CONST 0 (None)
22 RETURN_VALUE

在python opcod.h在 #define BUILD_CLASS    89    ceval.h创建类的伪指令:

case BUILD_CLASS:
u = TOP();
v = SECOND();
w = THIRD();
STACKADJ(-);
x = build_class(u, v, w);#调用到此函数
SET_TOP(x);
Py_DECREF(u);
Py_DECREF(v);
Py_DECREF(w);
break;
build_class(PyObject *methods, PyObject *bases, PyObject *name)
{
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) > ) {
base = PyTuple_GET_ITEM(bases, );
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)) {
/* A type error here likely means that the user passed
in a base that was not a class (such the random module
instead of the random.random type). Help them out with
by augmenting the error message with more information.*/ PyObject *ptype, *pvalue, *ptraceback; PyErr_Fetch(&ptype, &pvalue, &ptraceback);
if (PyString_Check(pvalue)) {
PyObject *newmsg;
newmsg = PyString_FromFormat(
"Error when calling the metaclass bases\n"
" %s",
PyString_AS_STRING(pvalue));
if (newmsg != NULL) {
Py_DECREF(pvalue);
pvalue = newmsg;
}
}
PyErr_Restore(ptype, pvalue, ptraceback);
}
return result;
}
#一般类继承自object,object的__class__属性是type,所有创建类时会调用到type的tp_call
PyObject *
PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw)
{
ternaryfunc call; if ((call = func->ob_type->tp_call) != NULL) {
PyObject *result;
if (Py_EnterRecursiveCall(" while calling a Python object"))
return NULL;
result = (*call)(func, arg, kw);
Py_LeaveRecursiveCall();
if (result == NULL && !PyErr_Occurred())
PyErr_SetString(
PyExc_SystemError,
"NULL result without error in PyObject_Call");
return result;
}
PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable",
func->ob_type->tp_name);
return NULL;
}
#ty_call又会调用到tp_new()函数
type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *obj; if (type->tp_new == NULL) {
PyErr_Format(PyExc_TypeError,
"cannot create '%.100s' instances",
type->tp_name);
return NULL;
} obj = type->tp_new(type, args, kwds);
if (obj != NULL) {
/* Ugly exception: when the call was type(something),
don't call tp_init on the result. */
if (type == &PyType_Type &&
PyTuple_Check(args) && PyTuple_GET_SIZE(args) == &&
(kwds == NULL ||
(PyDict_Check(kwds) && PyDict_Size(kwds) == )))
return obj;
/* If the returned object is not an instance of type,
it won't be initialized. */
if (!PyType_IsSubtype(obj->ob_type, type))
return obj;
type = obj->ob_type;
if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS) &&
type->tp_init != NULL &&
type->tp_init(obj, args, kwds) < ) {
Py_DECREF(obj);
obj = NULL;
}
}
return obj;
}

tp_new函数完成创建一个类的创建细节

再调用tp_ready