1.对象模型
在面向对象理论中类和对象是不同的概念,而在python中类也是对象,叫做类型对象。
所以python中的类,实例对象,类型都是对象。
元类型:
在python中实例对象的类型为对应类型的对象,而类型的对象为type对象,如下代码:
from Test2 import Test2
if __name__ == '__main__':
s = "abc"
extent=Test2() #Test2的实例化对象
print(type(s),type(str),type(type))
print(type(extent),type(Test2))
class Test2:
print("test")
输出结果
<class 'str'> <class 'type'> <class 'type'>
<class 'Test2.Test2'> <class 'type'>
type对象是所有对象的元类型,包括它自己的元类型也是,如图,不同类型对象的类型都指向元类型:
object类型
object类型是所有类型的基类型,也就是任何一个类都默认继承object类,除了他自己。这是因为继承必须有一个终点。
如下代码:
from Test2 import Test2
if __name__ == '__main__':
s = "abc"
extent=Test2() #Test2的实例化对象
print(issubclass(Test2,object))
print(issubclass(str, object))
print(issubclass(type, object))
对象的引用
在python中变量只是一个名字,保存指向实际对象的指针。
不可变对像
当对不可变对象进行修改时,由于不可变对象在对象创建后的整个生命周期,其值都不可进行修改
当进行修改操作时会将会以新数值创建一个新对象,变量的指针指向新对象
输出结果
也就是说当对不可变变量对象修改时,仅仅只会改变该变量的指针,使之指向新的对象,而其他指向旧对象的变量指针不会fa。
可变对象
变量修改操作可以对原对象进行修改
如图对列表的添加操作
列表对象内部维护了一个动态数组,存储元素对象的指针,当进行增减时修改对应元素指针即可
变长对象与定长对象
对象预分配的空间大小是否固定
常见的变长对象如:整型,字符串,列表
定长对象如:浮点对象
2.对象在python内部的存在形式
python由c语言构成,对象在python中是由结构体实现的
PyObject ,对象的基石
除结构体之外第一行为宏定义,第二行为引用计数,第三行为类型指针。
引用计数实现垃圾回收,类型指针指向对象的的类型对象,类型对象描述实例对象的数据及行为。
PyVarObject,变长对象
在PyObject的基础上添加上ob_size,用于记录元素的个数
头文件准备了两个宏定义,方便其他对象的使用
#define PyObject_HEAD PyObject ob_base;
#define PyObject_VAR_HEAD PyVarObject ob_base;
例如浮点对象,通过PyObject的宏+双精度浮点数double来实现
列表对象,PyValObject的宏+动态数组来实现
其中allocated用来记录列表的总容量,ob_item,指向动态数组的指针
初始化头部的宏定义
PyObject_HEAD_INIT对定长对象的初始化,将应用计数设为1并将对象类型设置为给定类型,其中
PyVarObject_HEAD_INIT 在PyObject_HEAD_INIT的基础上进一步设置长度字段
PyTyepObject,类型的基石
之前对象的结构已有引用次数,类型指针,以及变长对象的元素个数,但是缺少了对象的存储空间
以及此对象支持的操作。
其实上述联系通过ob_type参数来进行联系,它是类型指针,指向一个类型对象,其中的关键部分:
部分参数说明:
- 类型名称 ,即 tp_name 字段;
- 创建实例对象时所需的 内存信息 ,即 tp_basicsize 和 tp_itemsize 字段;
- 该类型支持的相关 操作信息 ,即 tp_print 、 tp_getattr 等函数指针;
图解
由于类型对象全局唯一,可以将类型对象定义成全局变量,如PyFloatObject对应的全局变量中叫做PyFloat_Type
PyType_Type,类型的类型
在之前了解到引用对象的类型为对应的类型对象,就如上述的PyTypeObject,记录了Float类型的内存大小及支持的操作,它与PyFloat通过ob_type 进行关联。
类型对象也是有类型的,那么它也是应该通过ob_type关联的对象记录type类型的内存大小及支持的操作。如图所示:
参考资料:Python 源码深度剖析-慕课专栏 (imooc.com)