在python中,值是靠引用来传递来的。
我们可以用 id()
来判断两个变量是否为同⼀个值的引用。 我们可以将id值理解为那块内存的地址标识。
# 1. int类型
a = 1
b = a
print(b) # 1
print(id(a)) # 140708464157520
print(id(b)) # 140708464157520
a = 2
print(b) # 1,说明int类型为不可变类型
print(id(a)) # 140708464157552,此时得到是的数据2的内存地址
print(id(b)) # 140708464157520
# 2. 列表
aa = [10, 20]
bb = aa
print(id(aa)) # 2325297783432
print(id(bb)) # 2325297783432
aa.append(30)
print(bb) # [10, 20, 30], 列表为可变类型
print(id(aa)) # 2325297783432
print(id(bb)) # 2325297783432
因为a的值赋给b,是通过引用传递的,所以,a和b占用的是同一块地址空间。但是由于int是不可变类型,所以,在修改a的值的时候,会额外的开辟一块新的地址空间来存放a的新值,因此b的值不会发生改变,如下图所示:
需要注意的是,如果你学习过c++,那么在c++里的引用(&),如果你改变了a,那么如果b是a的引用,b的值也将会发生改变。
def test1(a):
print(a)
print(id(a))
a += a
print(a)
print(id(a))
# int:计算前后id值不同
b = 100
test1(b)
print(b)
# 列表:计算前后id值相同
c = [11, 22]
test1(c)
print(c)
可以看到,int型的b变量在函数内计算前后,id发生了改变,而列表c的id没有改变,这和上面所说的是一致的。
由于列表是可变类型,所以函数内修改列表之后,列表在函数外面也发生了变化。
如果你想通过像c++的const那样的语法修饰一个变量,使其不会在函数内被改变,那么不好意思,python里面是没有const这个修饰符的。也就是python里面都是变量,不过,据说可以通过其他方式来实现const修饰符的效果,可以自己试一下!
三、了解引用可变和不可变类型
所谓可变类型与不可变类型是指:数据能够直接进行修改,不需要开辟新的地址空间来存储修改后的值。如果能直接修改那么就是可变,否则是不可变.
可变类型
- 列表
- 字典
- 集合
不可变类型
- 整型
- 浮点型
- 字符串
- 元组
只有可变类型可以在函数中被修改,但也是有约束条件的:只能用自带的一些方法进行修改,不能直接对其进行赋值。
f = {'name':'王宗轩','age':22}
g = [1,2,3,5,6]
def change1(f,q):
if q == 1:
f['name'] = 'Yukee'
if q == 2:
f.append(5)
change1(f,1)
change1(g,2)
print(f) #{'name': 'Yukee', 'age': 22}
print(g) #[1, 2, 3, 5, 6, 5]
f = {'name':'wu','age':8}
g = [1,2,3,5,6]
def change2(f,q):
if q == 1:
f = {'name':18}
if q == 2:
f = [1,5,6]
change2(f,1)
change2(g,2)
print(f) #{'name': 'wu', 'age': 8}
print(g) #[1, 2, 3, 5, 6]
可以看到,在change1函数里面修改列表和字典的时候,采用的是它们自带的一些属性,或者说是只是给某个元素赋值,所以函数外部的字典和列表也发生了改变。但是在change2函数里面,对字典和列表修改的时候是直接对整个字典和列表进行赋值,因此函数外部的字典和列表是没有发生改变的。