Python对象模型
一切皆对象
基本类型的数据是对象
不同于其他编程语言,在python
中,基本类型的数据也是对象,例如一个int
类型的数字是一个对象,一个str
类型的字符串也是一个对象。python
不在区分基本类型
和对象
,所有的基本类型
内部均由对象
实现。以int
整数为例,学习过python
的人都知道,在python
中int
类型的整数可以表示的范围是无限大的,那它在python
内部是怎样实现的呢,答案是整数数组
,这里的整数数组
中的整数
是指C语言
中的整数
。
>>> a = 1
>>> b = 'abc'
类型本身是对象
在python
中,类型本身也是对象,不管是基本的类型还是自定义的类型,在python
中也都是对象,int
类型是对象,str
类型是对象,class
定义的类型也是对象。
>>> int
<class 'int'>
>>>
>>> str
<class 'str'>
>>>
>>> class C:
... pass
...
>>> C
<class '__main__.C'>
在
python
中,我们可以把基本类型和自定义类型称为类型对象
,把通过类型对象
实例化得到的对象成为实例对象
。
image.png
类型、对象体系
我们都知道,编程语言中对象都是有自己的类型的,上面写的a=1
,大家都知道实例对象a
的类型是类型对象 int
,那么问题来了,既然在python中类型int
也是对象,称之为类型对象
,那么int类型对象
的类型是什么呢?在python
中使用内置的type函数
可以获取到对象的类型。
>>> type(int)
<class 'type'>
>>>
>>> type(str)
<class 'type'>
可以看到,int类型对象
的类型是type
,实际上不是内置的类型对象
的类型是type
,所有的自定义的类型对象
的类型也是type
。
>>> class C:
... pass
...
>>> type(C)
<class 'type'>
python中一切皆对象,type
也是对象,那么现在问题来了type对象
的类型是什么呢?
>>> type(type)
<class 'type'>
很惊奇的发现type对象
的类型竟然是type
本身。到此,我们可以得到一个类型关系图。

大家都知道在python3
中所有的自定义类型无论是否显示的声明都默认继承object
类型,其实内置类型也都是继承自object
对象的
>>> issubclass(int, object)
True
>>>
>>> class C:
... pass
...
>>> issubclass(C, object)
True
可以很清晰的使用内置的issubclass
函数判断出所有类型对象都继承自object
,object
就是python继承链
的最顶端,object
不可以继承其他的类型,因为在python
对象属性的查找需要一个终点。现在又有一个问题,object
是哪一种类型的创建的呢?
>>> type(object)
<class 'type'>
>>>
>>> issubclass(type, object)
True
通过上面的代码,很明显,python中object
类型对象的类型是type
,而type
类型又继承自object
。现在把继承关系在类型关系图中添加应该就是下面的样子。

现在,python中的各种对象的类型和继承关系都一目了然了。图中所有的实体在python
中都是以对象的形式存在的,那么在python
内部对象到底长什么样呢?接下来的文章会一一分析。
可变对象 与 不可变对象
可变对象
:创建后可以修改的对象
不可变对象
:创建后不可以修改的对象
可变对象
>>> l = [1, 2, 3]
>>> id(l)
4548721952
>>> l.append(4)
>>> id(l)
4548721952
不可变对象
>>> a = 1
>>> id(a)
4546064800
>>>
>>> a += 2
>>> id(a)
4546064832
对于不可变对象的修改,python
会重现创建一个新的对象,让变量名指向新的对象,然后删除旧的对象。
定长对象 与 变长对象
定长对象
:对象所占用的内存大小不会随着对象的值的变化而变化的对象
变长对象
:对象所占用的内存大小会随着对象的值的变化而变化的对象
可以使用python
内置sys模块
的getsizeof
函数获取一个对象的具体占用内存数量,得出的结果单位是字节。
>>> import sys
>>> sys.getsizeof(1)
28
>>> sys.getsizeof(100000000000)
32
>>> sys.getsizeof(1.)
24
>>> sys.getsizeof(100000000000.)
24
上面的演示中得出结论int
类型的实例对象是变长对象
,float
类型的实例对象是定长对象
,python
一切皆对象,只有研究对象的内部组成才能知道为什么有些对象是定长
的有些对象是变长
的,是否长度可变取决于对象的内部构造。