python中函数的参数传递(传值还是传引用)

函数的参数传递

函数参数传递有两种方式,传值和传引用,传值只是把变量的值复制一份给了实参,函数内部的操作不会改变函数外部变量的值,而传引用传递的是外部变量的地址,函数内部直接操作函数外部变量的储存空间,在调用函数之后,函数外部变量的值一般会改变

def Demo(a):
    a = a + 1
    print(id(a))

if __name__ == '__main__':
    a = 3
    print(id(a)) # 140705335465056
    Demo(a) # 140705335465088
    print(id(a)) # 140705335465056

看到变量a在函数调用前后地址值没有改变,证明在传递数值时传递的是变量的值,字符等类型也一样,然后尝试列表,元组

def Demo(a):
    a.append(3)
    print(id(a))

if __name__ == '__main__':
    s = [1,2]
    print("value = " + str(s) + "address = " + str(id(s)))  # value = [1, 2]address = 1574898786888
    Demo(s)  # value = [1, 2, 3]address = 1574898786888
    print("value = " + str(s) + "address = " + str(id(s)))  # value = [1, 2, 3]address = 1574898786888

函数调用前后地址值一致,证明传递的是引用,并且函数执行以后a的值也发生了改变,说明a.append()是在s的内存中操作的

如果传递的是元组,应为元组不可修改,所以三次输出的都是同一块地址,但其实以元组为参数传递时传递的是值。

还有一种情况

def Demo(a):
    a[0].append(3)
    print("value = " + str(a) + "address = " + str(id(a)))

if __name__ == '__main__':
    a = ([1,2], 2)
    print("value = " + str(a) + "address = " + str(id(a)))  # value = ([1, 2], 2)address = 2616967970056
    Demo(a)  # value = ([1, 2, 3], 2)address = 2616967970056
    print("value = " + str(a) + "address = " + str(id(a)))  # value = ([1, 2, 3], 2)address = 2616967970056

如果元组中的元素是列表,在调用函数前后,函数外部的a也发生了变化,根据刚开始说的,这感觉是在传引用,但其实不是,对于函数外部的a来说,他的第0个元素始终是<class 'list'>,至于列表中元素有没有发生变化,元组并不关心,元组判断元素有没有改变判断的是元素的地址有没有改变,而调用append()函数时,传递的是可变元素列表,地址值不会发生改变,这也就是为什么元组不可变,但如果元组中的数据是可变类型的话该数据就可变的原因

总结

python有两种数据类型,可变和不可变数据,对于可变数据类型,诸如列表,字典,集合在函数传参时传引用,对于不可变数据类型,如数值,字符,元组,在函数传参时传值,但更准确的来说,python函数传参时使用传对象引用的方式,如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值--相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象--相当于通过“传值’来传递对象。

最后还是要注意像元组中数据是可变类型的情况

参考链接1
参考链接2

发布了62 篇原创文章 · 获赞 33 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/zjbyough/article/details/95529933