在《python核心编程》中看到:“python 是通过引用调用的,... ,但对不可变对象而言,函数的行为将类似按值传递”。但是我尝试编写以下函数,输出却不是如料想的:
x = x * 2
print "local x : " ,x
#############
x = 1
func(x)
print "global x : ", x
这段代码的输出如下:
local x : 2
global x : 1
也就是说,所谓的传引用并没有发生,这个情况让人特别纠结,后来看了一个很好的博客:python传值还是传引用,知道一个道理:
在python中,strings, tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的对象。于是我又知道了对于数据而言,该行为将会导致生成一个新的临时对象,并对该临时对象进行操作。但是我又测试了以下代码,发现还是跟想象的不一样:
def func(x):
x = x * 2
print "local x : " ,x
#############
x = [1,2,3]
func(x)
print "global x : ", x
这段代码的输出为:
local x : [1,2,3,1,2,3]
global x : [1,2,3]
可以看出,这个时候仍然不是我们想象的传引用。但是随即将 func 函数改为如下形式:
def func(x):
x *= 2
print "local x : " ,x
则输出为:
local x : [1,2,3,1,2,3]
global x : [1,2,3,1,2,3]
这两个 func 函数的区别仅在于一个用的是等于乘法结果值,一个用的是乘等,在C++中,这两个操作的结果是一样的(虽然调用了不同的操作符)。但在
python 中,调用等号将会导致创建一个新的对象,这个对象与原对象并不是同一对象。所以第一个func 并没有改变全局 x 的值。
可以体会一下以下输出:
i = 1
id(i) #输出40404792
id(1) #输出40404792
i= 2
id(i) #输出40404780
dic = ['1']
id(dic) #输出40754232
dic = ['2']
id(dic) #输出47922912
dic *= 2
id(dic) #输出47922912