您的位置:首页 > 编程语言 > Python开发

python传值机制

2015-06-22 00:28 465 查看
首先要明确的是: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的变量本身不含数据,那么,在使用对象时,就只能靠变量去引用对象。然后再操作变量,达到操作数据对象的目的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: