彻底理解Python中对象、对象与变量引用的关系
一、对象(Object)
在Python里,一切皆对象,完全的面向对象。
Python中,所有的元素都是对象。
(对象是一个抽象,可想象成现实中的一个实际物体。)
1.对象定义:
对象是分配的一块内存,有足够的空间去表示它们所代表的值。—— 《Learning Python》
或者:一块内存空间,拥有特定的值,支持特定类型的相关操作。
2.对象的特点:
Python中,对象具有三要素:标识(identity)、类型(type)、值(value)。

标识(identity):
用于唯一标识对象,通常对应对象在计算机内存中的地址。
使用内置函数 id(obj) 返回对象唯一标识。
类型(type):
对象中含有标准的头部信息HEAD:类型标识符。
标识对象类型,表示对象存储的数据的类型。
类型可以限制对象的取值范围和可执行的操作。
使用内置函数 type(obj) 返回对象所属类型。
每一个对象都有两个标准的头部信息:
1.类型标识符,去标识对象的(数据)类型;
2.引用计数器,记录当前对象的引用的数目。
(回收机制:变量的引用计数器为0,自动清理。 ※ 较小整数型对象有缓存机制。)
值(value):
表示对象存储的数据的信息。
使用内置函数print(obj)可以直接打印值。
再看一遍图

操作符 is
和 ==
的区别与关系:
is
判断两个变量是否指向同一个对象,比较两个引用是否代表了内存中同一个地址,是否指向同一块内存空间。
通过 id(obj) 返回值判断。
==
比较对象的本身内容{类型(type)和值(value)}是否一致。
默认会调用对象的__eq__方法。
关系:
当id相同时,is 为True,两者的type和value肯定相同,
但当type与value相同时,== 为True,但两者的id不一定相同。
例如:
列表
整数
小整数 small_ints 和 短字符串缓存池
CPython出于性能优化的考虑,把频繁使用的整数对象用一个small_ints的对象池缓存起来。
small_ints缓存的整数值被设定为[-5, 256]这个区间。
如果使用CPython解释器,在任何引用这些整数的地方,都不需要重新创建int对象,而是直接引用缓存池中的对象。
如果整数不在该范围内,那么即便两个整数的值相同,它们也是不同的对象。
例如:
小整数
短字符串
3.对象的存储和创建:
Python中,对象存储在堆(heap)内存中。
对象通过调用__new__创建。
二、变量(Variable):
变量是一个系统表的元素,拥有指向对象的连接的空间。——《Learning Python》
Python中,
变量用来指向任意的对象,是对象的引用。
Python变量更像是指针,而不是数据存储区域。
变量,可看作对象的一个临时「标签」,是引用,
而非装有对象的容器。
例如:
房间门外挂着“张先生的房间”的门牌,
矿泉水瓶身上贴的一张写着“刘女士的矿泉水”的标签。
给一个变量赋值(Assignment),
等于把这个标签贴到一个对象上,
重新赋值,是撕下标签贴到另一个对象上。

上图给2个变量赋给一样的值,就相当于把2个标签贴在同一个对象上,
代码如下:
三、引用关系:
引用是自动形成的从变量到对象的指针。——《Learning Python》
在Python中,赋值(=)操作时,从变量到对象自动建立的连接关系,称为引用。
引用是一种关系,以内存中的指针的形式实现。
1.赋值操作:
是对象标识(identity)的传递,片面的理解是内存地址的传递。
变量一旦使用完毕,可被清理(撕掉标签)。
2.赋值语句:
Python赋值语句中,
当把一个对象(object)赋给一个数据结构元素或者变量名时,
Python总是会存储对象的引用,而不是对象的一个拷贝。
赋值操作符 =
定义变量的'=' 与数学中的'=' 意义不同。
Python 中的赋值符号'='的左边是变量名,右边是对象值Value,表示将右边的值传递给左边。
所以 '=' 是右连接性,对象值的传递顺序是从右到左。
Python中'=='是比较符号,代表左右值相等。
3.引用方式:
3.1简单引用:
一个对象 3 (int整数型,不可变对象),用变量名 a 表示:
Python中,从概念上,
a = 3 反映所有赋值语句执行的三个步骤:
1.创建一个对象来代表值 3 。
2.创建一个变量 a ,如果它还没有创建的话。
3.将变量 a 与 新的对象 3 相连接。

※ 需要明确 a 不是对象本身, a 只是对象 3 的引用。
3.2共享引用

a 指向对象3,
b = a 赋值引用,于是 b 也指向3。
a 和 b 都共同引用了同一个对象 3。
然后,
a 重新指向一个新对象'spam'(字符串,不可变对象),b 依然指向对象 3。

列表的共享引用
总结:
对象是分配的一块内存,有足够的空间去表示它们所代表的值。
变量是一个系统表的元素,拥有指向对象的连接的空间。
引用是自动形成的从变量到对象的指针。
补充:
Python 动态类型语言
变量不需要显示声明类型。对象的类型是内置的。
根据变量引用的对象,Python解释器自动跟踪对象的类型,从而确定类型,所以是动态型。
Python 强类型语言
每个对象都有数据类型,且只支持该类型支持的操作。
标识符:用于变量、函数、模块等的名称。
标识符命名规则:
1.区分大小写:如abc 和 ABC是不同的。
2.第一个字符必须是字母、下划线,其后的字符是:字母、数字、下划线。
3.不能使用关键字。如:if 、or、while等
4.双下线开头的和结尾的名称通常有特殊含义,尽量避免这种写法。如__init__是构造函数。
