今天遇到了python中值传递还是参数传递的问题,故记录
参考:https://www.jb51.net/article/127667.htm
python中的对象
不可变类型 | 可变类型 |
---|---|
Number(数字) | List(列表) |
String(字符串) | Dic(字典) |
Tuple(元组) | Sets(集合) |
如果函数收到的是一个可变对象(比如字典 或者列表)的引用,就能修改对象的原始值——相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能 直接修改原始对象——相当于通过“传值”来传递对象
举例:
list1=[1,2,3]
list2=[1,2,3]
a=1
b=1
print(id(list1))
print(id(list2))
print(id(a))
print(id(b))
#运行结果为
2391335958792 #list1的地址
2391318234376 #list2的地址
1863213216 #a的地址
1863213216 #b的地址
· 对于可变对象list来说,即便列表内容一模一样,python也会给它们分配新的不同的地址
· 对于不可变对象int ,内存里只有一个1。即便再定义一个变量c=1,也是指向内存中同一个1。也就是说,不可变对象1的地址是共享的。
·
看看函数中调用可变对象并修改它们的值是什么情况
list1=[1,2,3]
print(id(list1))
def a(x):
print(id(x))
x.pop()
print(x)
print(id(x))
x=x+[3]
print(x)
print(id(x))
a(list1)
#运行结果为
2391336040328
2391336040328
[1, 2]
2391336040328
[1, 2, 3]
2391335959048
把函数外的列表list1传递给函数后,x的地址和list是一样的
调用x本身的方法pop后,x变成[1,2],并且x的地址没变
但是给x赋值重新变成[1,2,3]以后,x的地址就变了。
也就是说,只要创建一个新的可变对象,python就会分配一个新的地址。就算创建的新可变对象和已存在的旧可变对象完全一样,python依旧会分配一个新的地址
而pop并不是创建新的可变对象,pop是对已有的可变对象进行修改,所以x.pop()后,x的地址没变
总结
在python中,不可变对象是共享的,创建可变对象永远是分配新地址