py一切皆对象:

那么Type也是个对象。对象类型叫PyTypeObject

demo

>>> a = 1
>>> a
1 >>> type(a)
<type 'int'> int类型 #等价的两个
>>> type(int) int类型的类型就是type
<type 'type'>
>>> type(type(a)) type(a)是int类型的类型就是type
<type 'type'> #还是等价的两个
>>> type(type(int))
<type 'type'>
>>> type(type(type(a)))
<type 'type'> # 1. int 的 类型 是`type`
>>> type(int)
<type 'type'>
# 2. type 的类型 还是`type`, 对应上面说明第二点
>>> type(type(int))
<type 'type'>

1. 首先, 定义一种类型对象叫PyTypeObject

定义

typedef struct _typeobject {

  /* MARK: base, 注意, 是个变长对象*/
PyObject_VAR_HEAD
const char *tp_name; /* For printing, in format "<module>.<name>" */ //类型名
Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */ // 创建该类型对象时分配的内存空间大小 // 一堆方法定义, 函数和指针
/* Methods to implement standard operations */
printfunc tp_print;
hashfunc tp_hash; /* Method suites for standard classes */
PyNumberMethods *tp_as_number; // 数值对象操作
PySequenceMethods *tp_as_sequence; // 序列对象操作
PyMappingMethods *tp_as_mapping; // 字典对象操作 // 一堆属性定义
.... } PyTypeObject;

说明

  • PyObject_VAR_HEAD 变长对象
  • const char *tp_name tp_name, 类型名字符串数组
  • 所有Type对象都是PyTypeObject的”实例”:
    • 比如int类型:PyType_Type/PyInt_Type

2. 然后, 用PyTypeObject初始化得到一个对象PyType_Type

定义

PyTypeObject PyType_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"type", /* tp_name */
sizeof(PyHeapTypeObject), /* tp_basicsize */
sizeof(PyMemberDef), /* tp_itemsize */
(destructor)type_dealloc, /* tp_dealloc */ // type对象的方法和属性初始化值
..... };

说明

  • tp_name

    类型名, 这里是”type”
  • PyVarObject_HEAD_INIT(&PyType_Type, 0)

    PyVarObject_HEAD_INIT, 这个方法在 Include/object.h中,

    等价于

    ob_refcnt = 1

    *ob_type = &PyType_Type

    ob_size = 0

    即, PyType_Type的类型是其本身!


3. 再然后, 定义具体的类型, 这里以PyInt_Type为例子

定义

PyTypeObject PyInt_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"int",
sizeof(PyIntObject),
0, // int类型的相关方法和属性值
.... (hashfunc)int_hash, /* tp_hash */ };

说明

  • “int”

    PyInt_Type的类型名是int
  • PyVarObject_HEAD_INIT(&PyType_Type, 0)

    PyInt_Type的

    *ob_type = &PyType_Type

使用
>>> type(1)
<type 'int'>
>>> type(type(1))
<type 'type'>

4. 最后, 生成一个整数对象int

定义

typedef struct {
PyObject_HEAD
long ob_ival;
} PyIntObject;

结构

  • PyIntObject为整数类型
  • 声明一个整数后得到整数对象
  • 对象ob_type指向PyInt_type对象

=========================

总结:

  1. 一切都是对象 什么都是PyObject/PyVarObject对象
  2. PyType_Type / PyInt_Type / PyString_Type ….等

    这些是类型对象, 可以认为是同级, 都是PyTypeObject这种类型的实例!
  3. 虽然是同级,

    但是其他PyXXX_Type, 其类型指向 PyType_Type

    PyType_Type 的类型指向自己, 它是所有类型的类型
  4. PyTypeObject 是一个变长对象
  5. 每个object, 例如PyIntObject都属于一种类型

    object初始化时进行关联

《Python 源码阅读》之 类型Type的更多相关文章

  1. PYTHON 源码阅读

    http://www.wklken.me/posts/2015/09/29/python-source-gc.html http://www.wklken.me/archives.html https ...

  2. FreeCAD源码阅读笔记

    本文目标在于记录在FreeCAD源码阅读中了解到的一些东西. FreeCAD编译 FreeCAD源码的编译最好使用官方提供的LibPack,否则第三方库难以找全,找到之后还需要自己编译,此外还不知道C ...

  3. python3 源码阅读-虚拟机运行原理

    阅读源码版本python 3.8.3 参考书籍<<Python源码剖析>> 参考书籍<<Python学习手册 第4版>> 官网文档目录介绍 Doc目录主 ...

  4. 【原】FMDB源码阅读(二)

    [原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...

  5. 读python源码--对象模型

    学python的人都知道,python中一切皆是对象,如class生成的对象是对象,class本身也是对象,int是对象,str是对象,dict是对象....所以,我很好奇,python是怎样实现这些 ...

  6. [PHP源码阅读]explode和implode函数

    explode和implode函数主要用作字符串和数组间转换的操作,比如获取一段参数后根据某个字符分割字符串,或者将一个数组的结果使用一个字符合并成一个字符串输出.在PHP中经常会用到这两个函数,因此 ...

  7. 源码阅读系列:EventBus

    title: 源码阅读系列:EventBus date: 2016-12-22 16:16:47 tags: 源码阅读 --- EventBus 是人们在日常开发中经常会用到的开源库,即使是不直接用的 ...

  8. EventBus源码解析 源码阅读记录

    EventBus源码阅读记录 repo地址: greenrobot/EventBus EventBus的构造 双重加锁的单例. static volatile EventBus defaultInst ...

  9. 36 网络相关函数(四)——live555源码阅读(四)网络

    36 网络相关函数(四)——live555源码阅读(四)网络 36 网络相关函数(四)——live555源码阅读(四)网络 简介 7)createSocket创建socket方法 8)closeSoc ...

随机推荐

  1. SVGImageView

    In essence, I'm trying to layer multiple ImageViews (one of which is a floor plan, the other a recta ...

  2. PHP中数据类型转换的三种方式

    PHP中数据类型转换的三种方式 PHP的数据类型转换属于强制转换,允许转换的PHP数据类型有: 1.(int).(integer):转换成整形2.(float).(double).(real):转换成 ...

  3. mysql查询orderby

    --按某一字段分组取最大(小)值所在行的数据 /* 数据如下: name val memo a    2   a2(a的第二个值) a    1   a1--a的第一个值 a    3   a3:a的 ...

  4. UVA-1335(UVALive-3177) Beijing Guards 贪心 二分

    题面 题意:有n个人为成一个圈,其中第i个人想要r[i]种不同的礼物,相邻的两个人可以聊天,炫耀自己的礼物.如果两个相邻的人拥有同一种礼物,则双方都会很不高兴,问最少需要多少种不同的礼物才能满足所有人 ...

  5. ubuntu的home目录下,Desktop等目录消失不见

    第一步:创建相应的文件夹 首先当然是创建几个相应的英文文件夹喽,比如:Desktop.Downloads. Documents. Music. Pictures. Videos  , Template ...

  6. POJ 1654 乱搞题?

    题意: 从一个点出发,8个方向,给出每一步的方向,求出走过的路径形成的多边形的面积. 思路: 先普及一下向量叉乘.. (摘自度娘) 也就是x1y2-x2y1. 那这不就好说了嘛. 一个经过原点的闭合多 ...

  7. Android WindowManager和WindowManager.LayoutParams的使用以及实现悬浮窗口的方法

    1.理清概念 我们使用过Dialog和PopupWindow,还有Toast,它们都显示在Activity之上.那么我们首先需要理解的是android中是如何去绘制这些UI的呢?这里我只讲我所理解的, ...

  8. Hibernate中解决No Hibernate Session bound to thread问题

    引用:忘了 首先是getCurrentSession()与openSession()的区别: 1.getCurrentSession()与openSession()的区别? * 采用getCurren ...

  9. 【Oracle】SCOPE=MEMORY|SPFILE|BOTH

    SCOPE=MEMORY|SPFILE|BOTH 指示了修改参数时的“作用域”: SCOPE=MEMORY :只在实例中修改,重启数据库后此次修改失效. SCOPE=SPFILE :只修改SPFILE ...

  10. 高手的C++学习忠告,虚心学习下~~[转载]

    1.把C++当成一门新的语言学习(和C没啥关系!真的.): 2.看<Thinking In C++>,不要看<C++变成死相>: 3.看<The C++ Programm ...