Python 函数参数传值还是传引用?

参考资料:

1、Python值传递还是引用传递   https://blog.csdn.net/xinxin957_/article/details/81873074

2、Python是值传递?引用传递? https://blog.csdn.net/apple9005/article/details/52125670?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158358768319726867816314%2522%252C%2522scm%2522%253A%252220140713.130056874..%2522%257D&request_id=158358768319726867816314&biz_id=0&utm_source=distribute.pc_search_result.none-task

示例:

代码一:

  1. list1 = ['a','b','c','d','e','f','g']
  2. num = len(list1)
  3. def func1(a,b):
  4.     print(id(a),id(b))
  5.     a.pop(0)
  6.     b -= 1
  7.     print(id(a),id(b))
  8.     return
  9.  
  10. print(list1,num)
  11. print(id(list1),id(num))
  12. func1(list1,num)
  13. print(list1,num)
  14. print(id(list1),id(num))

运行结果:

['a', 'b', 'c', 'd', 'e', 'f', 'g'] 7                   # 变量list1和num的内容
3024548553288 140708972385504 # 变量list1所引用的内存 和 变量num所引用的内存
3024548553288 140708972385504 # 刚进入函数func1时,参数a和b的值是对list1和num的引用
3024548553288 140708972385472 # 因为list1是可变对象,对a进行a.pop(0)操作时,a所引用的内容就是list1的内容

                                              # 因为num是不可变对象,在进行 b -= 1运算时,先把原来b引用的内容进行复制,b再引用新的内存
['b', 'c', 'd', 'e', 'f', 'g'] 7                        # 函数执行完之后,list1改变,num没有改变
3024548553288 140708972385504 # 变量list1所引用的内存 和 变量num所引用的内存 都没有变化

代码二:

  1. A = 100
  2. B = A
  3. print(id(A),id(B))
  4. A -= 1
  5. print(id(A),id(B))
  6. print(A,B)

运行结果:

140708972388480 140708972388480 # A、B都引用相同的内存
140708972388448 140708972388480 # 对A 进行操作时,因为A是不可变对象,内存被2个变量引用,因此复制原对象内容后,把A指向新的对象,然后再对A应用的对象进行操作
99 100                                                   # A的值改变,B因为还引用原来的对象,内容没有改变

代码三:

对本文开头的第二篇文章的引用进行说明

  1. def spam(eggs):
  2.     print(id(eggs))
  3.     eggs.append(1)
  4.     print(id(eggs))
  5.     eggs = [2, 3]
  6.     print(id(eggs))
  7.     
  8. ham = [0]
  9. print(id(ham))
  10. spam(ham)
  11. print(id(ham))
  12. print(ham)

运行结果:

2576493339208 # 变量ham引用对象的地址
2576493339208 # 刚进入函数时,参数eggs引用的相同的对象
2576493339208 # 因为 ham(eggs) 是list,为可变对象,对eggs引用的对象操作也是对ham引用的对象操作
2576493339272 # 重新对eggs赋值(引用新的对象),eggs为新的对象的地址
2576493339208 # ham 没有被重新赋值,所以引用的对象一直没有变
[0, 1]                   # ham 应用的对象在函数中被改变

总结:

        Python中所有的变量都是对象(object),变量都是对象的引用(可以理解为对象的地址)。

        Python中函数参数的传递是传引用的方式,传递参数时,是传递原参变量的引用(可以理解为传递原变量引用对象的地址)。

        Python中把对象(Object)分为可变对象(list、dict、set等)和不可变对象(number、string、tuple等)。当在函数中对参数所引用的对象进行改变时,如果对象是可变对象,则直接进行对象内容的改变,反应到程序中,我们就看到了函数外的原来的参数被改变;如果对象是不可变对象时,则先在内存中复制一个对象的副本,参数引用同时改为指向这个副本,然后再对这个副本的内容进行操作,改变的是副本。见“代码一”。

        如果多个变量引用同一个不可变对象时,当对一个变量的值进行改变时,先复制一个新的对象副本,再将变量指向新的对象副本,然后再进行改变对象的操作。见“代码二”。

        如果多个变量引用同一个可变对象时,对其中一个变量重新赋值后,这个变量引用新的对象,其他变量还是引用原来的对象。见“代码三”函数中的eggs。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值