在C++等语言中,变量的声明和赋值是可以分开的
int a;
a = 343;
而在python中却不行,在声明python变量的同时必须进行赋值操作
a = 343
如果你直接使用一个不存在的变量,就会发生错误,NameError: name 'b' is not defined
a = 343 这样代码被执行时,首先要在内存中创建出343这个对象,然后让a指向它,这便是引用。
此后,我们在程序中使用变量a时,其实都是在使用343,python可以通过a找到343, 这是对引用最通俗的解释。
赋值语句执行过程中,有一点极容易被忽略掉,那就是这个过程中,在内存中创建了新的数据
a = [1]
b = [1]
print(a == b)
print(a is b)
两行赋值语句,分别将列表[1] 赋值给a 和 b,表达式 a == b 的结果是Ture,因为他们的内容的确相同,但表达式a is b的结果是False, 因为这两行赋值语句执行过程中,一共创建了两个列表,他们只是内容相同而已,但内存地址绝对不相同,下图是这两个变量的内存描述示意图
下面的代码会输出变量的内存地址与类型
a = 343
print(id(a))
print(type(a))
程序输出为
4325858928
<class 'int'>
虽然标题是“变量的内存地址和类型”,但从本质上来说,内存地址是343的内存地址,类型是343的类型。
如果将a 的指向改变,即将另外一个值赋值给a, 那两行print输出的内容就会发生变化
a = 343
print(id(a))
print(type(a))
print('改变a的指向')
a = 'python'
print(id(a))
print(type(a))
程序输出
4325858928
<class 'int'>
改变a的指向
4339812760
<class 'str'>
这究竟是怎么一回事呢,下图展示了变量a改变指向的过程
变量a最终指向了字符串'python', 而343由于没有变量指向它,因此引用数量从1变成了0。
python的变量,总是要指向一个内存中的数据才行,因此,它不能孤立的存在。
a = 343
b = a
print(id(a))
print(id(b))
程序输出为
4325858928
4325858928
变量a的内存地址和变量b的内存地址一样,下图是这种情况的示意图
这两个变量都指向了 343, 因此343的引用数量是2
当一个数据没有变量指向它时,这个数据的引用数量就变成了0,python会销毁掉这种对象,这就是GC(垃圾回收),你可以通过sys.getrefcount() 方法查看一个数据的引用数量。
下面这段代码,一定要在python交互式解释器下执行,因为其他环境下,会做优化处理,导致实际结果与理论结果不符。
Python 3.6.3 (v3.6.3:2c5fed86e0, Oct 3 2017, 00:32:08)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> a = 343
>>> b = a
>>> sys.getrefcount(a)
3
所以,最终343的引用数量是是3
QQ交流群: 211426309