Python函数参数传递机制

Python3中有6中标准的数据类型:

  • Number(数字)
  • String(字符串)
  • List(列表)
  • Tuple(元组)
  • Set(集合)
  • Dictionary(字典)

其中Number、String、Tuple和Sets是不可变类型,List和Dictionary是可变类型。

什么是可变类型?什么是不可变类型?

1. 可变类型

  对不可变类型的变量重新赋值,实际上是重新创建一个不可变类型的对象,并将原来的变量重新指向新创建的对象(如果没有其他变量引用原有对象的话(即引用计数为0),原有对象就会被回收)。

  我们以Number类型为例,定义a=1,当a的值发生变化后,则a的内存地址发生了变化,用id()可查看变量的内存地址:

>>> a = 1
>>> id(a)
1503521232
>>> a = 2
>>> id(a)
1503521264

而如果令a=1,再令b=1,我们看a和b的内存地址:

>>> a = 1
>>> b = 1
>>> id(a)
1503521232
>>> id(b)
1503521232

但如果是两个大小相同的浮点数,发现它们并不是指向同个内存地址,这点和int类型不同(这与Python内存管理机制有关,Python对int类型和较短的字符串进行了缓存,无论声明多少个值相同的变量,实际上都指向同个内存地址)。

>>> a = 1.5
>>> b = 1.5
>>> id(a)
30347720
>>> id(b)
30347696
>>> a += 1
>>> a
2.5
>>> id(a)
30347576

2. 不可变类型

我们以list为例,当list的内容发生变化时,还是指向同个内存地址,因为list是可变类型,可以在原处修改。

>>> a = [1, 2, 3]
>>> id(a)
39059528
a.append(4)
>>> id(a)
39059528

当存在多个值相同的list变量时,他们分别指向不同的内存地址。

>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> id(a)
39060744
>>> id(b)
39059528

当把列表a直接赋给列表b时,他们指向同样的内存地址,因此当a改变时,b也随之改变。

>>> a = [1, 2, 3]
>>> b = a 
>>> a.append(4)
>>> b 
[1, 2, 3, 4]
>>> id(a)
39060936
>>> id(b)
39060936

3. 传参机制

  Python中有两种函数的传参机制:值传递和引用传递。看下面的例子会更加直观。

  • 值传递
def swap(x, y):
    x, y = y, x
    print('函数中 x = ', x, ' y = ', y)
    return x, y

x = 10
y = 20
print('函数调用前 x = %d, y = %d' % (x, y))
swap(x, y)
print('函数调用后 x = %d, y = %d' % (x, y))

打印结果如下:

函数调用前 x = 10, y = 20
函数中x = 20, y = 10
函数调用后 x = 10, y = 20

可以看到,我们在函数中对两个Number变量的值进行了交换,但函数运行之后,发现两个变量的值并未交换。

  • 引用传递

如果我们把输入的变量换成是列表:

def swapList(lst):
    lst[0], lst[1] = lst[1], lst[0]
    print('函数中 lst = ', lst)

lst = [1,2]
print('函数调用前 lst = ', lst)
swapList(lst)
print('函数调用后 lst = ', lst)

打印结果如下:

函数调用前 lst =  [1, 2]
函数中 lst =  [2, 1]
函数调用后 lst =  [2, 1]

可以看到,列表中的值确实发生了交换。

  是什么原因导致我们传递Number类型时没有交换成功,但传递List类型时就交换成功了。

  这是因为当我们传递Number类型时,swap函数的形参是实参的副本,也就是在函数内部会复制一份x和y,然后进行交换,所以实际中并没有交换实参x y的值。

  但对于可变类型,数据是存储在堆中,栈中只存储了引用,所以在修改形参数据时实参会改变。

欢迎关注微信公众号:Quant_Times
在这里插入图片描述

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值