python函数参数值传递和引用传递的区别

作为刚上完编译原理等专业课的小朋友,忍不住来看看函数参数传递过程中的内存情况,记录一下心路历程。

首先查资料,发现python不允许程序员选择采用传值还是传引用。

  • 如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值——相当于通过“传引用”来传递对象
  • 如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象——相当于通过“传值’来传递对象。

我对于内存情况的预期是:

  • 对于“传引用”的情况,形参和实参应该占用相同的内存区域
  • 对于“传值”的情况,形参和实参应该占用不同的内存区域

测试一下,“传引用”符合预期:

def func(list1):
	print(id(list1))  # 1460765511816
	list1[0] = 666
	
list1 = [1,2,3]
print(id(list1))  # 1460765511816
func(list1)
print(list1)  # [666,2,3]

“传值”比较有意思:

def func(x):
	print(id(x))  # 1756475584,不符合预期
	x = 2
	print(id(x))  # 1756475616

x = 1
print(id(x))  # 1756475584
func(x)

可以看到,在对形参x进行“写”操作(x=2)之前,形参x和实参x地址相同,即并没有为形参x开辟新的内存空间,这不符合我之前的预期;“写”操作后,id(x)的结果就发生了变化,此时很明显这个x就不是之前的x了。猜测这应该是一种懒惰的做法,类似于“写时复制(copy-on-write)”。

的确,如果我们在函数内部只对x进行“读”操作,没必要产生一个新的局部变量,让栈无意义地增长消耗内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值