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

python class的创建的更多相关文章

  1. python 读写、创建 文件

    python中对文件.文件夹(文件操作函数)的操作需要涉及到os模块和shutil模块. 得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd() 返回指定目录下的所有文件和目 ...

  2. 使用Python Shapefile Library创建和编辑Shapefile文件

    介绍 shapefile是GIS中非常重要的一种数据类型,在ArcGIS中被称为要素类(Feature Classes),主要包括点(point).线(polyline)和多边形(polygon).P ...

  3. python 读写、创建 文件的方法(必看)

    python 读写.创建 文件的方法(必看) 更新时间:2016年09月12日 10:26:41 投稿:jingxian 我要评论下面小编就为大家带来一篇python 读写.创建 文件的方法(必看). ...

  4. python 一次创建多级目录

    python 一次创建多级目录沙漠骆驼:qq音乐import osos.mkdirs('/home/user/app')

  5. 使用python type动态创建类

    使用python type动态创建类 X = type('X', (object,), dict(a=1))  # 产生一个新的类型 X 和下列方法class X(object):    a = 1效 ...

  6. python之multiprocessing创建进程

    python的multiprocessing模块是用来创建多进程的,下面对multiprocessing总结一下使用记录. multiprocessing创建多进程在windows和linux系统下的 ...

  7. python读写、创建文件、文件夹等等

    python中对文件.文件夹(文件操作函数)的操作需要涉及到os模块和shutil模块. 得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd() 返回指定目录下的所有文件和目 ...

  8. Python命令行创建虚拟环境

    Python命令行创建虚拟环境 安装virtualenv 启动命令行,执行命令pip install -U virtualenv 创建一个新的虚拟环境 执行命令python -m virtualenv ...

  9. python进阶ing——创建第一个Tornado应用

    python进阶ing——创建第一个Tornado应用 分类: Python2013-06-02 23:02 1725人阅读 评论(2) 收藏 举报 pythonTornado 每天在群里跟很多群友讨 ...

  10. Python测试开发-创建模态框及保存数据

    Python测试开发-创建模态框及保存数据 原创: fin  测试开发社区  前天 什么是模态框? 模态框是指的在覆盖在父窗体上的子窗体.可用来做交互,我们经常会看到模态框用来登录.确定等等,到底是怎 ...

随机推荐

  1. Problem F: 平面上的点——Point类 (VI)

    Description 在数学上,平面直角坐标系上的点用X轴和Y轴上的两个坐标值唯一确定.现在我们封装一个“Point类”来实现平面上的点的操作. 根据“append.cc”,完成Point类的构造方 ...

  2. postman接口测试基础知识

    接口文档访问地址:http://doc.nnzhp.cn/index.php?s=/6&page_id=8 1.什么是接口:从数据库里面取数据或是插入数据 接口测试:测接口一定要有接口文档-- ...

  3. Python IDE:pycharm

    ------------------------------------------------------安装pycharm------------------------------------- ...

  4. grep语法2

    grep 参数 -n  :显示行号-o  :只显示匹配的内容-q  :静默模式,没有任何输出,得用$?来判断执行成功没有,即有没有过滤到想要的内容 -l  :如果匹配成功,则只将文件名打印出来,失败则 ...

  5. linux基础命令一

    linux基础命令一 1.date命令 date命令介绍:显示或者设置系统日期 date命令的语法: 显示日期:date  [options...]  [+FORMAT] FORMAT:为显示日期的格 ...

  6. Redis之在Linux上安装和简单的使用

    我只是一个搬运工 Redis之在Linux上安装和简单的使用https://blog.csdn.net/qq_20989105/article/details/76390367 一.安装gcc 1.R ...

  7. centOS连接没问题,使用SecureCRT就不能连接

    原因: 将NAT模式改为自定义的模式即可:

  8. BIOS(Basic Input/Output System)是基本输入输出系统的简称

    BIOS(Basic Input/Output System)是基本输入输出系统的简称 介绍 操作系统老师说,平时面试学生或者毕业答辩的时候他都会问这个问题,可见这个问题对于计算机专业的学生来说是如此 ...

  9. linux下查询java进程以及杀掉其进程

    1.使用命令: ps -ef|grep java 查询到到自己想要kill掉的进程id 2.使用命令: kill -9 id(这里的id为你上一步查找到的id)

  10. redis hset hmset过期时间

    hmset m k v > hset m k v (integer) > hget m k "v" > expire m (integer) > ttl m ...