2016.06.14更新:
又踩坑了,百度后得到解决,参考链接:
python:函数传参是否会改变函数外参数的值
入参变化
当函数中传入可变对象时:
- 函数体传入的参数 , 为函数体外变量引用的副本 .
- 在函数体中改变变量指向的堆中的值 , 对函数外变量有效.
- 在函数体中改变变量的引用 , 对函数外变量无效
e.g
def test1(a):
b = [3, 2, 1]
a = b #不会改变
def test2(a):
a.append(4) #会改变
if __name__ == '__main__':
a = [1, 2, 3]
test1(a)
print(a) #[1, 2, 3]
test2(a)
print(a) #[1, 2, 3, 4]
原文:
可变对象与不可变对象
- 可变对象:dict、list、自定义对象等,修改时内存地址不会发生变化。在函数中对其进行修改会改变在函数外部时的值。
- 不可变对象:tuple、str、int等,修改时内存地址会发生变化,即返回一个新的修改后的对象。在函数中对其进行修改不会改变在函数外部时的值。
参数传递
先来看一个例子:
def test(b=[]):
print(id(b))
b += [1]
print(b)
print(id(b))
test() # [1]
test() # [1, 1]
test() # [1, 1, 1]
运行结果:
2392714224520
[1]
2392714224520
2392714224520
[1, 1]
2392714224520
2392714224520
[1, 1, 1]
2392714224520
可以看到,因为b的默认值[ ]是一个可变变量,故在每一次运行test函数时b的内存地址没有发生变化,导致值发生改变。
对比:
def test(b=1):
print(id(b))
b += 1
print(b)
print(id(b))
test() # 2
test() # 2
test() # 2
输出:
140716401815296
2
140716401815328
140716401815296
2
140716401815328
140716401815296
2
140716401815328
那么问题来了,在函数中设置了b的默认值,为什么没有每次运行都初始化一次呢?
原因是,在python中函数本身也是一个对象,这个对象只在定义的时候初始化一次,参数的默认值也随着只初始化一次,所以看到每次运行函数时b的内存地址都是一样的。
网友评论