参考了《python学习手册》这本书,还有在网上找的一些资料。分享一下,也算单个总结。
1.引用
看下面的例子:
a = 3
在开始学习python的时候,我的认识比较浅薄,单纯的认为i这只是一个简单的赋值语句。随着学习的深入。逐步了解到。这一行代码意味着什么。
- 先创建一个对象来代表3.
- 再创建一个变量a
- 将变量与新的对象3相连接。
这行代码就算执行了。
那么引用是什么呢?
在python中从变量到对象的连接称作引用。也就是,引用是一种关系,通过内存中的指针的形式来实现。具体的来说:
- 变量是一个系统表的入口,包含了指向对象的连接。
- 对象是被分配到的一块内存,有足够的空间去表示它们所代表的值。
- 引用是自动形成的从变量到对象的指针。
注:我对引用比较形象的理解,宠物狗是具体的对象,名字就是变量。我创建一个变量,意味着取个名字。这个名字和宠物狗连接到了一起。每当我喊这个名字,那个狗就会响应我的呼喊。每当我使用这个变量,这个变量连接的对象也将为我所用。当然这只能是我个人的理解,并不是那么准确。
2.共享引用
看下面的例子
a = 3
b = a
a = 'spam'
我们还可以试下列表,集合等可变类型。
a = [1, 2, 3]
b = a
a = [4, 5, 6]
运行赋值语句b=a 之后。变量b成为对象3的一个引用。在内部变量b实际上一个指针指向了对象的空间。这样的,视为共享引用。因为变量a,和变量b都指向了对象3.
为了判断这种情况,我们可以使用两种方法,配合使用id()函数来打印它的内存地址。验证这样的执行情况。
注:id函数。返回对象的“标识”。这是一个整数(或长整数),保证该对象在其生命周期内是唯一且不变的。具有非重叠生存期的两个对象可能具有相同的id()值。
还可以来个判断第一种是“==运算符”。第二种“is”.is 判断,可以判断对象的同一性。它返回一个布尔值,True或者是False。
print(a)
print(b)
print(id(a))
print(id(b))
print( a is b)
3.固定地址和临时地址
在自己尝试打印中,又发现一些有趣的现象。就是每一次打印的时候。打印的id是不一样的。这就牵涉到另外一个概念。就是固定地址和临时地址。这里我接触到一个python源码的概念,叫做缓冲池。针对一些高频常用的数据,有确定的内存地址,不会改变。
使用固定内存地址存储数据如下:
-5到256的整数(小整数对象池)
True和False
由字母、数字、下滑线组成的字符串
使用临时内存地址存储数据如下:
小于-5后大于256的整数
所有小数
包含字母、数字、下滑线之外的字符组成的字符串
我们可以尝试一下打印256 和257的id。多打印几次,来验证看看。
print(id(256))
print(id(257))
还有需要特别注意的是事情就是。
a = [1]
b = [1]
print(a is b)
执行上述代码,返回的是一个False。每当创建一个对象,python都会开辟一个新的内存空间。这样理解,a is b就好理解了。当然。这样说不是很准确。
a = tuple()
b = tupel()
print( a is b)
执行上述代码,返回的是一个True,所有的空元组共用一个内存地址。当然这个内存地址是临时地址,它是变化的。
我查了比较多的资料。这个跟python内部的存储机制有关系,
这里贴出一个链接。是我在上网搜索的。当然只要你感兴趣。都可以搜的到。
https://www.hongweipeng.com/index.php/archives/1630/
注:我们可以用到getsizeof()查看内存大小,和getrefcount()查看引用次数。帮助理解。