python:万物皆对象!

python函数传参是值传递还是引用传递:
值传递:
即只给一个值给被调函数,被调用的函数会在内部开辟内存空间放函数放进来的值,这时候,函数无论怎么操作都不会影响外部实参的值。
引用传递: 就是把这个实参的变量的地址,直接给了被调函数,被调函数就是直接操作这个地址里面的值。

抽象化一下: 可能不太准确着时候我们把整个变量抽象化为一份写满文字的文件,如果这时候同学A拿着这份文件,把文件的内容告诉同学B,同学B记下来这些内容并且把内容放到文件上,然后无论怎么二次创作都不会影响同学A手上那份文件,这便是值传递。相对的,如果同学A是直接把这份文件给了同学B,这时候,同学B操作这个B手上的文件,同学A手上的文件也会变化,因为,现实意义上而已,这特么就是同一份。

回过头来看看python的变量传参

def test(c):
    print("传入变量的id",id(c))
    # 对c执行操作 也就是这时候B同学开始对他手上的文件开始二次创作了
    c += 2
    print("二次创作之后变量的id",id(c))
a = 2
# 传参之前的变量id
print("传参之前的变量id",id(a))
test(a)
#传参之后的变量id
print("传参之后的变量id",id(a))

执行之后效果如下

传参之前的变量id 1451650096
传入变量的id 1451650096
二次创作之后变量的id 1451650160
传参之后的变量id 1451650096

看到上面的效果,这时候我们要分析一下了,等于说,我们函数传参之后,在对这个文件进行二次创作之前,,他们id都是一样的,也就是说同学B手上的文件和同学A手上的文件是同一份,那是不是说明python是"引用传递"了呢? 再看看文件二次操作之后,这时候,id值又变了,也就是说,同学B二次加工这个文件之后,他手上的文件和同学A不一样了?!怎么会这样,如果是"引用传递"这个id值不应该是同一个吗,他们操作的文件不应该是同一份吗?!难道是同学A在同学B操作的时候换了文件?!带着这个疑问, 我们继续看第四行打印的结果,传参之后的文件id 这个值还是和之前的一样,也就是说,其实同学A是没有换他的文件的,这里就更加迷茫了。
所以我们要跳开到底是值传递还是引用传递的思考,其实python本身是没有绝对意义的值传递和引用传递的。我们知道python本身是有可变类型和不可变类型的说法的,其实对于可变数据类型,具有增删改查的特性,进行增删改查的时候并没有赋值操作,所以没有绑定新的对象,对同一个引用或称为同一个对象进行增删改查之后,变量指向的还是该对象。所以进行的是引用传递的形式。arg在执行append之前,实参变量b把自己引用对象的地址也给了arg,所以对arg进行操作的时候对引用对象b也进行了修改。

def bar(args):
    args.append(1) 
 
b = []
print(b)# 输出:[]
print(id(b)) # 输出:4324106952
bar(b)
print(b) # 输出:[1]
print(id(b))  # 输出:4324106952

结论:
python不允许程序员选择采用传值还是传引用。python参数传递采用的肯定是“传对象引用”的方式。这种方式相当于传值和传引用的一种综合。如果函数收到的是一个不可变对象(数字、字符或元组)的引用,就不能直接修改原始对象–相当于通过‘值传递’来传递对象。如果函数收到的是一个可变对象(字典、列表)的引用,就能修改对象的原始值–相当于‘传引用’来传递对象。
严格的说我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值