Python参数传递:值传递和引用传递

前提:

1、Python 中万物皆为对象,变量以引用的方式指向对象。
2、身份

    2.1 可变对象:对象的内存值可以被改变,引用变量改变后,实际上是其所指向的值发生了变化,当前这块内存区域中存放的内容发生了改变,包括:list dict set;

    2.2 不可变对象:对象的内存值不能被改变,如果变量引用了不可变的对象,当改变该变量时,由于其所指向的对象的值不能都被改变,因此需要把原来的值复制出来一份后再改变;即在内存中开辟一块新的区域,变量再指向这个新的区域地址,那么变量就引用了新的对象,包括:tuple string int float bool

值传递(passl-by-value)过程中,被调函数的形式参数作为被调函数的局部变量处理,即在堆栈中开辟了内存空间来存放由主调函数放进来的实参的值,从而想成为了实参的一个副本。值传递的特点是被调函数对形参的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。

示例:

def ChangeInt(a):
    a = 10
    print('函数内a的内存地址:',id(a))
a = 2
print('执行函数前,a的内存地址:', id(a))
ChangeInt(a)
print('执行函数后,a的内存地址:', id(a))
print('a =',a)

执行结果:

执行函数前,a的内存地址: 8791093155632
函数内a的内存地址: 8791093155888
执行函数后,a的内存地址: 8791093155632
a = 2

可以看出,实参a的变量引用前后未发生变化。形参a指向了内存中的新地址。

引用传递(pass-by-reference)过程中,被调函数的形式参数虽然也作为局部变量在堆栈中开辟了内存空间,但这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过堆栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做任何的操作都影响了主调函数中的实参变量。

示例:

def changeme(mylist):
    mylist.append([1,2,3,4])
    print("函数内取值: ", mylist)
    print('函数内的内存地址:',id(mylist))
    return
mylist = [10,20,30]
changeme(mylist)
print("函数外取值: ",mylist)
print('函数外的内存地址:', id(mylist))

执行结果:

函数内取值:  [10, 20, 30, [1, 2, 3, 4]]
函数内的内存地址: 34405056
函数外取值:  [10, 20, 30, [1, 2, 3, 4]]
函数外的内存地址: 34405056

可以看出,形参的变化影响了实参。实参、形参指向了内存中的同一个地址。

python参数传递采用的是“传对象引用”的方式。这种方式相当于传值和传引用的一种结合。如果函数收到的是一个可变对象(字典、列表、集合)的引用,就能修改对象的原始值--相当于‘传引用’来传递对象。如果函数收到的是一个不可变对象(数字、字符或元组)的引用,就不能直接修改原始对象--相当于通过‘值传递’来传递对象。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值