标签: python
在 Python
中
id()
函数可以查看变量中保存数据所在的 内存地址注意:如果变量已经被定义,当给一个变量赋值的时候(用
=
符号),本质上是 修改了数据的引用
- 变量 不再 对之前的数据引用
- 变量 改为 对新赋值的数据引用
比如下面的例子:
a = 1
print(id(a))
print(id(1))
a
就是变量,1
就是数据。你会发现两个输出的结果是一样的,代表a和1的地址相同。
如果你在代码下面加入了a = 2
那么在输出id(a)
则发现和上面的结果不一样了,这就说明了a更换了指向的地址。所以在python中,使用=
这个赋值语句是修改了引用的指向。
但是一定要注意是使用的=
赋值语句这样才是修改引用位置。
在python中数据类型有数值型、字符串型、元组、列表、字典,其中数值型、字符串型、元组都是不可变类型,而列表、字典都是可变类型,那么可变类型和不可变类型有什么区别呢。不可变类型就是一旦数据被定义,那么就不可以修改,比如你定义了a=1
,对于1
这个数据是不可被修改的,如果你使用赋值语句a=2
,那么你修改的是a的引用,把a指向了2,但并不能改变1
这个位置的值,所以就叫做不可变类型,而对于可变类型,比如列表,你如果想要改变列表内容,那么可以使用一些方法比如.append
对列表里面的数据进行修改。
l = [1,2,3]
print(id(l))
l.append(4)
print(id(l))
上面的例子,虽然l从[1,2,3]变为了[1,2,3,4]但是l的id是没有变的,相当于下面这个图表示:
注意:上面使用的.append
方法,如果你还是使用**赋值(=)**语句,那么对于可变类型也是修改的引用地址,比如把l.append(4)
修改为l = [1,2,3,4]
你会发现id就不同了。因为内存中又建立了一块存储的[1,2,3,4]
。
所以对于可变类型与不可变类型来说,通过赋值语句都是修改的指向地址,只是对于可变类型来说,还提供了方法来进行修改内容。
在python中函数的参数其实传递的就是引用。比如下面这个代码:
def t1(a):
pass
b = 1
t1(a)
在函数中的a
在外面的b
其实指向的是一个东西。
赋值=
语句修改,这时在函数里面修改的东西不会影响到函数外面,因为赋值相当于重新指向了。考虑下面的代码:
def t1(a,l1,l2):
a = 2
l1 =[]
l2.append(7)
b = 3;g_l1 = [1,2];g_l2 = [1,2,3]
t1(b,g_l1,g_l2)
print(b,g_l1,g_l2)
可以发现b的值没有修改,因为是不可变类型并且在函数中使用的是赋值语句,所以相当于函数中的a重新指向了,所以不会影响到b。而g_l1同样没被修改,因为虽然g_l1是可变类型,但是由于在函数内部使用的是赋值语句,所以相当于l1也重新指向了,所以对g_l1不会产生影响,但是对于g_l2和l_2来说,由于是可变类型,而l2又是通过方法来修改的,所以会对函数外部的产生影响。
从一个错误说起TypeError: unhashable type: 'list'
,可能在初学的时候会遇见这样的问题,这是在对字典定义的时候,我们用可变类型作为了字典的key,因为字典的key是使用哈希算法进行哈希运算,这样就会增大取数据的速度,而对于哈希算法来说,传入的数据一定要是不可变的,因为这样计算的值才会唯一,否则你传入一个可变的,可能这一次经过哈希算法计算的是一个数,而再一次可能就算出来不一样了,所以在对于字典的key只能使用数值型、字符串以及元组作为key。