python传值机制

首先要明确的是:Python参数传递采用的 都是按引用传递。
那么,有人就会有 疑惑:为什么数字,字符串,元组的等看起开好像是类似于C语言的按值传递, 而list,dict又像是C++的引用传递呢?

我认为,这是因为:python中有可变对象和不可变对象之分。

对可变对象都来说,就好象是按引用传递,对不可变对象来说,就好象是按值传递。我们还是来弄清到底为什么是这个现象。


#!/usr/bin/env python3
#-*-coding:utf-8-*-

x = 5

def test(x):
    print('函数里的x变量的最初地址是:',id(x))
    x+=1
    print("加1操作后,函数里的x变量的值是:", x)
    print('加1操作后,函数里变量x的地址是:',id(x))



if __name__=='__main__':
    print('最开始x的地址是:',id(x))
    test(x)
    print('最后,函数外x变量的值是:',x)




运行结果:

>>>
最开始x的地址是:                          1619120656
函数里的x变量的最初地址是:        1619120656
加1操作后,函数里的x变量的值是: 6
加1操作后,函数里变量x的地址是: 1619120672
最后,函数外x变量的值是:             5

我们发现,最开始x的地址  和   函数里的x变量的最初地址是一样 的,说明传递的的确是引用。也就是函数里的局部变量x和函数外的全局变量x都引用同一个对象 5 。问题是:当函数里的变量x进行+1操作后,x引用的地址变了,说明:x不再引用对象 5,而是重新引用了临时对象 6.。那么为什么python不让原来地址为1619120656的整数5在原地变为6,而是另外临时创建一个整型对象6,再让函数里的 x去引用?这就是因为:int 类 对象是不可变对象。


也即是说:在地址为:1619120656的这个数据不可更改,只读不可写。

画个图

当函数调用完毕,局部变量就会被销毁,相当于del x ,内存对象 6 没有被任何变量引用,就会被垃圾回收。也就是在内存上被清理。全局变量x最终还是引用对象5,没有任何改变。python之所以这样设计,我想是考虑到代码的安全和管理。因为数字,字符串等类型是最常用的,如果代码里有n处同时引用了一个数字,其中有1处操作将此数字改变了,n-1处也不会改变,这确实是一件好事。


那么对于可变对象,大家应引申一下就明白了。由于是可变对象,只要在某一处通过某个操作被改变,那n-1处也就会随之更新。




最后,看看ython的内存管理:

Python中的每个对象都有一个引用计数,用来计数该对象在不同场所分别被引用了多少次。每当引用一次Python对象,相应的引用计数就增1,每当消毁一次Python对象,则相应的引用就减1,只有当引用计数为零时,才真正从内存中删除Python对象,也就是垃圾回收。


还要说明的一点是:既然python中,一切皆对象,那么,在使用数据对象时,除了字面值外,一切皆引用。

因为python的变量本身不含数据,那么,在使用对象时,就只能靠变量去引用对象。然后再操作变量,达到操作数据对象的目的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值