学习Python:为何两个操作列表的函数运行后修改结果不一致?
Python函数参数修改差异原因解析
先放示例代码方便对照:
def fun1(a): a=[7, 8] def fun2(a): a[0]=7 a[1]=8 q=[1,2] fun1(q) print(q) # 输出 [1, 2] fun2(q) print(q) # 输出 [7, 8]
核心底层逻辑
Python的参数传递规则是传对象引用,通俗来说:函数接收的是外部变量指向的内存对象的地址,但是函数内部的参数名本身是局部作用域下的独立变量名,两种操作的差异本质是「重新绑定局部变量名」和「修改原内存对象」的区别。
两个函数的具体差异
- fun1的操作:
a = [7, 8]属于重新绑定局部变量
执行这条赋值语句前,局部变量a确实和外部的q指向同一个列表对象;但赋值语句会创建一个新的列表[7,8],并让局部变量a指向这个新对象,此时a和q的指向完全脱离,后续操作不会影响q指向的原对象,所以外部打印q还是原来的[1,2]。 - fun2的操作:
a[0] =7、a[1]=8属于修改原对象的内容
全程没有改变局部变量a的指向,a始终和q指向同一个列表对象,直接修改该对象的内部元素,相当于直接改了q指向的列表的内容,所以外部打印q能看到修改结果。
快速验证方法
可以打印变量的内存id验证逻辑:
def fun1(a): print("fun1赋值前a的id:", id(a)) # 和外部q的id一致 a=[7, 8] print("fun1赋值后a的id:", id(a)) # 和外部q的id不同,指向新对象 def fun2(a): print("fun2修改前a的id:", id(a)) # 和外部q的id一致 a[0]=7 a[1]=8 print("fun2修改后a的id:", id(a)) # 仍然和外部q的id一致,指向不变 q=[1,2] print("外部q的id:", id(q)) fun1(q) print(q) fun2(q) print(q)
内容的提问来源于stack exchange,提问作者Behzad Danaei
相关产品推荐
相关产品推荐

