登录  | 加入社区

黑狼游客您好!登录后享受更多精彩

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

查看: 599|回复: 0

Python 源码阅读:类型

[复制链接]

216

主题

1

帖子

0

现金

黑狼菜鸟

Rank: 1

积分
0
发表于 2017-12-3 18:17:49 | 显示全部楼层 |阅读模式 来自 四川
(点击上方蓝字,快速关注我们)



来源:wklken
如有好文章投稿,请点击 → 这里了解详情


这篇主要涉及Python对象的类型机制


有点绕, 一定要思维清晰的时候再看哦:)


一个例子


[color=#006FE0 !important]>>> [color=#002D7A !important]a[color=#006FE0 !important] = [color=#009999 !important]1
[color=#006FE0 !important]>>> a
[color=#009999 !important]1
 
[color=#006FE0 !important]>>> [color=teal !important]type[color=#333333 !important]([color=#002D7A !important]a[color=#333333 !important])
 
[color=#B85C00 !important]#等价的两个
[color=#006FE0 !important]>>> [color=teal !important]type[color=#333333 !important]([color=teal !important]type[color=#333333 !important]([color=#002D7A !important]a[color=#333333 !important]))
 
[color=#006FE0 !important]>>> [color=teal !important]type[color=#333333 !important]([color=#800080 !important]int[color=#333333 !important])
 
[color=#B85C00 !important]#还是等价的两个
[color=#006FE0 !important]>>> [color=teal !important]type[color=#333333 !important]([color=teal !important]type[color=#333333 !important]([color=teal !important]type[color=#333333 !important]([color=#002D7A !important]a[color=#333333 !important])))
 
[color=#006FE0 !important]>>> [color=teal !important]type[color=#333333 !important]([color=teal !important]type[color=#333333 !important]([color=#800080 !important]int[color=#333333 !important]))


我们反向推导一个int对象是怎么生成的.




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


代码位置 Include/object.h


定义


[color=#006FE0 !important] typedef[color=#006FE0 !important] [color=#800080 !important]struct[color=#006FE0 !important] [color=teal !important]_typeobject[color=#006FE0 !important] [color=#333333 !important]{
 
[color=#006FE0 !important]  [color=#999999 !important]/* MARK: base, 注意, 是个变长对象*/
[color=#006FE0 !important]  [color=teal !important]PyObject_VAR_HEAD
[color=teal !important]  [color=#800080 !important]const[color=#006FE0 !important] [color=#800080 !important]char[color=#006FE0 !important] *[color=#002D7A !important]tp_name[color=#333333 !important];[color=#006FE0 !important] [color=#999999 !important]/* For printing, in format "." */[color=#006FE0 !important] [color=#999999 !important]//类型名
[color=#006FE0 !important]  [color=teal !important]Py_ssize_t [color=#002D7A !important]tp_basicsize[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]tp_itemsize[color=#333333 !important];[color=#006FE0 !important] [color=#999999 !important]/* For allocation */[color=#006FE0 !important] [color=#999999 !important]// 创建该类型对象时分配的内存空间大小
 
[color=#006FE0 !important]  [color=#999999 !important]// 一堆方法定义, 函数和指针
[color=#006FE0 !important]  [color=#999999 !important]/* Methods to implement standard operations */
[color=#006FE0 !important]  [color=teal !important]printfunc [color=#002D7A !important]tp_print[color=#333333 !important];
[color=#006FE0 !important]  [color=teal !important]hashfunc [color=#002D7A !important]tp_hash[color=#333333 !important];
 
[color=#006FE0 !important]  [color=#999999 !important]/* Method suites for standard classes */
[color=#006FE0 !important]  [color=teal !important]PyNumberMethods *[color=#002D7A !important]tp_as_number[color=#333333 !important];[color=#006FE0 !important]   [color=#999999 !important]// 数值对象操作
[color=#006FE0 !important]  [color=teal !important]PySequenceMethods *[color=#002D7A !important]tp_as_sequence[color=#333333 !important];[color=#006FE0 !important] [color=#999999 !important]// 序列对象操作
[color=#006FE0 !important]  [color=teal !important]PyMappingMethods *[color=#002D7A !important]tp_as_mapping[color=#333333 !important];[color=#006FE0 !important] [color=#999999 !important]// 字典对象操作
 
[color=#006FE0 !important]  [color=#999999 !important]// 一堆属性定义
[color=#006FE0 !important]  [color=#333333 !important]....
 
[color=#333333 !important]}[color=#006FE0 !important] [color=#002D7A !important]PyTypeObject[color=#333333 !important];


说明


[color=#009999 !important]1.[color=#006FE0 !important] [color=#002D7A !important]tp[color=#333333 !important]_name
类型名[color=#333333 !important],[color=#006FE0 !important] 这里是[color=#DD1144 !important]"type"
 
[color=#009999 !important]2.[color=#006FE0 !important] [color=teal !important]PyVarObject_HEAD_INIT[color=#333333 !important]([color=#006FE0 !important]&[color=#002D7A !important]PyType_Type[color=#333333 !important],[color=#006FE0 !important] [color=#009999 !important]0[color=#333333 !important])
[color=#002D7A !important]PyVarObject_HEAD_INIT[color=#333333 !important],[color=#006FE0 !important] 这个方法在[color=#006FE0 !important] [color=#002D7A !important]Include[color=#006FE0 !important]/[color=#800080 !important]object[color=#333333 !important].h中[color=#333333 !important],
等价于
[color=#006FE0 !important]        [color=#002D7A !important]ob_refcnt[color=#006FE0 !important] = [color=#009999 !important]1
[color=#006FE0 !important]        *[color=#002D7A !important]ob_type[color=#006FE0 !important] = &[color=teal !important]PyType_Type
[color=teal !important]        [color=#002D7A !important]ob_size[color=#006FE0 !important] = [color=#009999 !important]0
 
即[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]PyType[color=#333333 !important]_Type的类型是其本身[color=#006FE0 !important]![color=#009999 !important]1.[color=#006FE0 !important] [color=#002D7A !important]tp[color=#333333 !important]_name
类型名[color=#333333 !important],[color=#006FE0 !important] 这里是[color=#DD1144 !important]"type"
 
[color=#009999 !important]2.[color=#006FE0 !important] [color=teal !important]PyVarObject_HEAD_INIT[color=#333333 !important]([color=#006FE0 !important]&[color=#002D7A !important]PyType_Type[color=#333333 !important],[color=#006FE0 !important] [color=#009999 !important]0[color=#333333 !important])
[color=#002D7A !important]PyVarObject_HEAD_INIT[color=#333333 !important],[color=#006FE0 !important] 这个方法在[color=#006FE0 !important] [color=#002D7A !important]Include[color=#006FE0 !important]/[color=#800080 !important]object[color=#333333 !important].h中[color=#333333 !important],
等价于
[color=#006FE0 !important]        [color=#002D7A !important]ob_refcnt[color=#006FE0 !important] = [color=#009999 !important]1
[color=#006FE0 !important]        *[color=#002D7A !important]ob_type[color=#006FE0 !important] = &[color=teal !important]PyType_Type
[color=teal !important]        [color=#002D7A !important]ob_size[color=#006FE0 !important] = [color=#009999 !important]0
 
即[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]PyType[color=#333333 !important]_Type的类型是其本身[color=#006FE0 !important]!


所有Type都是PyTypeObject的”实例”: PyType_Type/PyInt_Type




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


代码位置 Objects/typeobject.c


定义


[color=teal !important]PyTypeObject [color=#002D7A !important]PyType_Type[color=#006FE0 !important] = [color=#333333 !important]{
[color=#006FE0 !important]  [color=teal !important]PyVarObject_HEAD_INIT[color=#333333 !important]([color=#006FE0 !important]&[color=#002D7A !important]PyType_Type[color=#333333 !important],[color=#006FE0 !important] [color=#009999 !important]0[color=#333333 !important])
[color=#006FE0 !important]  [color=#DD1144 !important]"type"[color=#333333 !important],[color=#006FE0 !important]                                     [color=#999999 !important]/* tp_name */
[color=#006FE0 !important]  [color=teal !important]sizeof[color=#333333 !important]([color=#002D7A !important]PyHeapTypeObject[color=#333333 !important]),[color=#006FE0 !important]                   [color=#999999 !important]/* tp_basicsize */
[color=#006FE0 !important]  [color=teal !important]sizeof[color=#333333 !important]([color=#002D7A !important]PyMemberDef[color=#333333 !important]),[color=#006FE0 !important]                        [color=#999999 !important]/* tp_itemsize */
[color=#006FE0 !important]  [color=#333333 !important]([color=#002D7A !important]destructor[color=#333333 !important])[color=#002D7A !important]type_dealloc[color=#333333 !important],[color=#006FE0 !important]                   [color=#999999 !important]/* tp_dealloc */
 
[color=#006FE0 !important]  [color=#999999 !important]// type对象的方法和属性初始化值
[color=#006FE0 !important]  [color=#333333 !important].....
 
[color=#333333 !important]};


说明


[color=#009999 !important]1.[color=#006FE0 !important] [color=#002D7A !important]tp[color=#333333 !important]_name
类型名[color=#333333 !important],[color=#006FE0 !important] 这里是[color=#DD1144 !important]"type"
 
[color=#009999 !important]2.[color=#006FE0 !important] [color=teal !important]PyVarObject_HEAD_INIT[color=#333333 !important]([color=#006FE0 !important]&[color=#002D7A !important]PyType_Type[color=#333333 !important],[color=#006FE0 !important] [color=#009999 !important]0[color=#333333 !important])
[color=#002D7A !important]PyVarObject_HEAD_INIT[color=#333333 !important],[color=#006FE0 !important] 这个方法在[color=#006FE0 !important] [color=#002D7A !important]Include[color=#006FE0 !important]/[color=#800080 !important]object[color=#333333 !important].h中[color=#333333 !important],
等价于
[color=#006FE0 !important]        [color=#002D7A !important]ob_refcnt[color=#006FE0 !important] = [color=#009999 !important]1
[color=#006FE0 !important]        *[color=#002D7A !important]ob_type[color=#006FE0 !important] = &[color=teal !important]PyType_Type
[color=teal !important]        [color=#002D7A !important]ob_size[color=#006FE0 !important] = [color=#009999 !important]0
 
即[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]PyType[color=#333333 !important]_Type的类型是其本身[color=#006FE0 !important]![color=#009999 !important]1.[color=#006FE0 !important] [color=#002D7A !important]tp[color=#333333 !important]_name
类型名[color=#333333 !important],[color=#006FE0 !important] 这里是[color=#DD1144 !important]"type"
 
[color=#009999 !important]2.[color=#006FE0 !important] [color=teal !important]PyVarObject_HEAD_INIT[color=#333333 !important]([color=#006FE0 !important]&[color=#002D7A !important]PyType_Type[color=#333333 !important],[color=#006FE0 !important] [color=#009999 !important]0[color=#333333 !important])
[color=#002D7A !important]PyVarObject_HEAD_INIT[color=#333333 !important],[color=#006FE0 !important] 这个方法在[color=#006FE0 !important] [color=#002D7A !important]Include[color=#006FE0 !important]/[color=#800080 !important]object[color=#333333 !important].h中[color=#333333 !important],
等价于
[color=#006FE0 !important]        [color=#002D7A !important]ob_refcnt[color=#006FE0 !important] = [color=#009999 !important]1
[color=#006FE0 !important]        *[color=#002D7A !important]ob_type[color=#006FE0 !important] = &[color=teal !important]PyType_Type
[color=teal !important]        [color=#002D7A !important]ob_size[color=#006FE0 !important] = [color=#009999 !important]0
 
即[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]PyType[color=#333333 !important]_Type的类型是其本身[color=#006FE0 !important]![color=#009999 !important]1.[color=#006FE0 !important] [color=#002D7A !important]tp[color=#333333 !important]_name
类型名[color=#333333 !important],[color=#006FE0 !important] 这里是[color=#DD1144 !important]"type"
 
[color=#009999 !important]2.[color=#006FE0 !important] [color=teal !important]PyVarObject_HEAD_INIT[color=#333333 !important]([color=#006FE0 !important]&[color=#002D7A !important]PyType_Type[color=#333333 !important],[color=#006FE0 !important] [color=#009999 !important]0[color=#333333 !important])
[color=#002D7A !important]PyVarObject_HEAD_INIT[color=#333333 !important],[color=#006FE0 !important] 这个方法在[color=#006FE0 !important] [color=#002D7A !important]Include[color=#006FE0 !important]/[color=#800080 !important]object[color=#333333 !important].h中[color=#333333 !important],
等价于
[color=#006FE0 !important]        [color=#002D7A !important]ob_refcnt[color=#006FE0 !important] = [color=#009999 !important]1
[color=#006FE0 !important]        *[color=#002D7A !important]ob_type[color=#006FE0 !important] = &[color=teal !important]PyType_Type
[color=teal !important]        [color=#002D7A !important]ob_size[color=#006FE0 !important] = [color=#009999 !important]0
 
即[color=#333333 !important],[color=#006FE0 !important] [color=#002D7A !important]PyType[color=#333333 !important]_Type的类型是其本身[color=#006FE0 !important]!


结构


第一张图, 箭头表示实例化(google doc用不是很熟找不到对应类型的箭头)


S3e5P3fed7NQ5Qpw.jpg
第二张图, 箭头表示指向


b98C660zHPxKyX6X.jpg
使用


[color=#B85C00 !important]# 1. int 的 类型 是`type`
[color=#006FE0 !important]>>> [color=teal !important]type[color=#333333 !important]([color=#800080 !important]int[color=#333333 !important])
 
[color=#B85C00 !important]# 2. type 的类型 还是`type`, 对应上面说明第二点
[color=#006FE0 !important]>>> [color=teal !important]type[color=#333333 !important]([color=teal !important]type[color=#333333 !important]([color=#800080 !important]int[color=#333333 !important]))


注意: 无论任何时候, ob_type指向的是 PyTypeObject的实例: PyType_Type/PyInt_Type…




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


代码位置 Objects/intobject.c


定义


[color=teal !important]PyTypeObject [color=#002D7A !important]PyInt_Type[color=#006FE0 !important] = [color=#333333 !important]{
[color=#006FE0 !important]  [color=teal !important]PyVarObject_HEAD_INIT[color=#333333 !important]([color=#006FE0 !important]&[color=#002D7A !important]PyType_Type[color=#333333 !important],[color=#006FE0 !important] [color=#009999 !important]0[color=#333333 !important])
[color=#006FE0 !important]  [color=#DD1144 !important]"int"[color=#333333 !important],
[color=#006FE0 !important]  [color=teal !important]sizeof[color=#333333 !important]([color=#002D7A !important]PyIntObject[color=#333333 !important]),
[color=#006FE0 !important]  [color=#009999 !important]0[color=#333333 !important],
 
[color=#006FE0 !important]  [color=#999999 !important]// int类型的相关方法和属性值
[color=#006FE0 !important]  [color=#333333 !important]....
 
[color=#006FE0 !important]  [color=#333333 !important]([color=#002D7A !important]hashfunc[color=#333333 !important])[color=#002D7A !important]int_hash[color=#333333 !important],[color=#006FE0 !important]                         [color=#999999 !important]/* tp_hash */
 
[color=#333333 !important]};


说明


[color=#009999 !important]1.[color=#006FE0 !important] [color=#DD1144 !important]"int"
[color=#002D7A !important]PyInt[color=#333333 !important]_Type的类型名是[color=#800080 !important]int
 
[color=#009999 !important]2.PyVarObject_HEAD_INIT[color=#333333 !important]([color=#006FE0 !important]&[color=#002D7A !important]PyType_Type[color=#333333 !important],[color=#006FE0 !important] [color=#009999 !important]0[color=#333333 !important])
[color=#002D7A !important]PyInt[color=#333333 !important]_Type的
 
[color=#006FE0 !important]    *[color=#002D7A !important]ob_type[color=#006FE0 !important] = &[color=#002D7A !important]PyType_Type


结构


NV1Zop5BWQai336I.jpg


使用


[color=#006FE0 !important]>>> [color=teal !important]type[color=#333333 !important]([color=#009999 !important]1[color=#333333 !important])
[color=#006FE0 !important]
 
[color=#006FE0 !important]>>> [color=teal !important]type[color=#333333 !important]([color=teal !important]type[color=#333333 !important]([color=#009999 !important]1[color=#333333 !important]))
[color=#006FE0 !important]




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


代码位置 Include/intobject.h


定义


typedef[color=#006FE0 !important] [color=#800080 !important]struct[color=#006FE0 !important] [color=#333333 !important]{
[color=#006FE0 !important]    [color=teal !important]PyObject_HEAD
[color=teal !important]    [color=#800080 !important]long[color=#006FE0 !important] [color=#002D7A !important]ob_ival[color=#333333 !important];
[color=#333333 !important]}[color=#006FE0 !important] [color=#002D7A !important]PyIntObject[color=#333333 !important];


结构


gHnObRXZHtTzB7r2.jpg


[color=#009999 !important]1.[color=#006FE0 !important] PyIntObject为整数类型
 
[color=#009999 !important]2.[color=#006FE0 !important] 声明一个整数后得到整数对象
 
[color=#009999 !important]3.[color=#006FE0 !important] 对象[color=#002D7A !important]ob[color=#333333 !important]_type指向[color=#002D7A !important]PyInt[color=#333333 !important]_type对象




到这里, 总结下


[color=#006FE0 !important] [color=#009999 !important]1.[color=#006FE0 !important] 一切都是对象
 
[color=#006FE0 !important] [color=#009999 !important]2.[color=#006FE0 !important] [color=#002D7A !important]PyType_Type[color=#006FE0 !important] / [color=#002D7A !important]PyInt_Type[color=#006FE0 !important] / [color=#002D7A !important]PyString[color=#333333 !important]_Type[color=#006FE0 !important] [color=#333333 !important]....
[color=#006FE0 !important] 这些是[color=#333333 !important]`类型对象[color=#333333 !important]`,[color=#006FE0 !important] 可以认为是同级[color=#333333 !important],[color=#006FE0 !important] 都是PyTypeObject这种[color=#333333 !important]`类型[color=#333333 !important]`的实例[color=#006FE0 !important]!
 
[color=#006FE0 !important] [color=#009999 !important]3.[color=#006FE0 !important] 虽然是同级[color=#333333 !important],
[color=#006FE0 !important] 但是其他[color=#002D7A !important]PyXXX_Type[color=#333333 !important],[color=#006FE0 !important] 其类型指向[color=#006FE0 !important] [color=teal !important]PyType_Type
[color=teal !important] [color=#002D7A !important]PyType[color=#333333 !important]_Type[color=#006FE0 !important] 的类型指向自己[color=#333333 !important],[color=#006FE0 !important] 它是所有类型的[color=#333333 !important]`类型[color=#333333 !important]`
 
[color=#006FE0 !important] [color=#009999 !important]4.[color=#006FE0 !important] PyTypeObject[color=#006FE0 !important] 是一个变长对象
 
[color=#006FE0 !important] [color=#009999 !important]5.[color=#006FE0 !important] 每个[color=#800080 !important]object[color=#333333 !important],[color=#006FE0 !important] 例如PyIntObject都属于一种[color=#333333 !important]`类型[color=#333333 !important]`
[color=#006FE0 !important] [color=#800080 !important]object初始化时进行关联




多态是如何实现的?


对象的多态, 例如hash


[color=#006FE0 !important]>>> [color=teal !important]hash[color=#333333 !important]([color=#009999 !important]1[color=#333333 !important])
[color=#009999 !important]1
[color=#006FE0 !important]>>> [color=teal !important]hash[color=#333333 !important]([color=#DD1144 !important]"abc"[color=#333333 !important])
[color=#009999 !important]1453079729188098211


从上面数据结构可以看到, 方法及属性, 在不同Type实例化时就确定了


[color=teal !important]PyTypeObject [color=#002D7A !important]PyInt_Type[color=#006FE0 !important] = [color=#333333 !important]{
[color=#006FE0 !important]    [color=#333333 !important]...
[color=#006FE0 !important]    [color=#333333 !important]([color=#002D7A !important]hashfunc[color=#333333 !important])[color=#002D7A !important]int_hash[color=#333333 !important],[color=#006FE0 !important]                         [color=#999999 !important]/* tp_hash */
[color=#006FE0 !important]    [color=#333333 !important]...
[color=#333333 !important]}
 
[color=teal !important]PyTypeObject [color=#002D7A !important]PyString_Type[color=#006FE0 !important] = [color=#333333 !important]{
[color=#006FE0 !important]    [color=#333333 !important]...
[color=#006FE0 !important]    [color=#333333 !important]([color=#002D7A !important]hashfunc[color=#333333 !important])[color=#002D7A !important]string_hash[color=#333333 !important],[color=#006FE0 !important]                      [color=#999999 !important]/* tp_hash */
[color=#006FE0 !important]    [color=#333333 !important]...
[color=#333333 !important]}


Python内部传递的是泛型指针PyObject *, 函数调用时, 找到其类型* ob_type, 然后调用


object -> ob_type -> tp_hash


即: 大量函数指针决定了该类型的具体行为


看完本文有收获?请转发分享给更多人

关注「Python开发者」,提升Python技能

j93s3v0h65QVD3OA.jpg




上一篇:Python 最难的问题
下一篇:Python Web 框架介绍
您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

 

QQ|申请友链|小黑屋|手机版|Hlshell Inc. ( 豫ICP备16002110号-5 )

GMT+8, 2024-5-15 23:43 , Processed in 0.132073 second(s), 47 queries .

HLShell有权修改版权声明内容,如有任何爭議,HLShell將保留最終決定權!

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表