本文只分析Python类实例的创建,不涉及类本身的构建(类本身的构建将会在接下来的文章中介绍)。
# example
class A(object):
pass
obj_a = A()
上面这一段代码对应的opcode如下:
0 LOAD_CONST 1 ('A')
3 LOAD_GLOBAL 0 (object)
6 BUILD_TUPLE 1
9 LOAD_CONST 2 (<code object A at 0x104f367b0, file "<stdin>", line 2>)
12 MAKE_FUNCTION 0
15 CALL_FUNCTION 0
18 BUILD_CLASS
19 STORE_FAST 0 (A)
22 LOAD_FAST 0 (A)
25 CALL_FUNCTION 0
28 STORE_FAST 1 (obj_a)
说明几个关键的opcode,BUILD_CLASS用于创建一个名为A的Class,在LOAD_FAST的时候Python虚拟机加载A,然后执行CALL_FUNCTION。
1.从CALL_FUNCTION机器码看起
下面是从CALL_FUNCTION开始的函数调用流程:
CALL_FUNCTION->call_function->do_call->PyObject_Call...
PyObject_Call从函数命名很容易理解,这个函数是对PyObject进行调用。
PyObject *
PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
if ((call = func->ob_type->tp_call) != NULL) {
...
result = (*call)(func, arg, kw);
...
}
...
func在这里对应的就是类A,当然我们在创建obj_a的时候是没有参数的,因此arg和kw便没有任何东西。在if语句中获取func->ob_type->tp_call,func就是A,那么ob_type在这里是PyType_Type。
# in typeobject.c
PyTypeObject PyType_Type = {
....
(ternaryfunc)type_call, /* tp_call */
....
就是上面这个实例,其对应的tp_call是type_call这个函数。
static PyObject *
type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) {
....
obj = type->tp_new(type, args, kwds);
....
type->tp_new中的type还是类A,tp_new则是其基类object的tpnew(原因很简单,我们在A的定义中并没有重载\_new__函数),object的真面目就是PyBaseObject_Type。
# in typeobject.c
PyTypeObject PyBaseObject_Type = {
....
object_new, /* tp_new */
....
2.object_new都做了什么
static PyObject *
object_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
....
return type->tp_alloc(type, 0);
}
object_new做的事情很简单,就是调用类A的tp_alloc,这里的tp_alloc的实现是PyType_GenericAlloc函数,我们在前文也提到过。
3.总结
到这里obj_a的创建流程基本走完,无非后面会调用tpnew(如果我们定义了\_init__就会调用我们的这个方法),但obj_a在内存中的形式已经确定,就是一个简单的PyObject。
typedef struct _object {
PyObject_HEAD
} PyObject;
其ob_type对应的就是类A。