python基础学习(可变与不可变对象)(一)

0.可变与不可变对象,赋值、浅拷贝与深拷贝,函数参数传值

1.第一个题目

a = [1,2]
b = a
print(id(a), id(b))
print(id(a[0]), id(b[0]))
b[0] = 3
print(a, b)
print(id(a[0]), id(b[0]))
print(id(a), id(b))

其结果如下:
在这里插入图片描述
可以看到,对一个list来说,a指向的是list的地址,a[0]指向的是值1的地址,b=a,b指向的也是list的地址,在给b[0]赋值的时候,因为1是一个不可变对象,对于指向它的变量的赋值,其实就是指向了一个新的不可变对象,所以地址发生了改变,但是a,b指向的是list的地址,那个地址并没有发生改变

结论就是,常见对象分为可变对象和不可变对象;可变对象有:list,dict,set;不可变对象有:str,int,bool,tuple,float。对可变对象的赋值,两者指向同一个可变对象的地址(引用);对不可变对象的赋值,会生成一个新的不变对象并返回地址

2.第二个题目

import copy
def copy_test():
    a = {"x": [1, 2, 3, 4], "u": 123}
    b = a
    d = copy.deepcopy(a)
    e = copy.copy(a)
    e["x"][0] = 3
    e["u"] = 234
    print(id(a) == id(e))
    print(a)

copy_test()

结果如下:
在这里插入图片描述
深拷贝自然不用说,完全是独立的;赋值之前的题目也有说明;主要考虑下浅拷贝的情况,浅拷贝时,a和e的地址已经不同(引用了不同的对象),但是value还是指向了相同的对象,这时继续需要考虑value是可变对象还是不可变对象来决定后续的赋值变化

因此,对于赋值,浅拷贝,深拷贝来说,区别如下:

2.1 赋值

b = a: 赋值引用,a 和 b 都指向同一个对象
在这里插入图片描述

2.2 浅拷贝

b = a.copy(): 浅拷贝, a 和 b 是一个独立的对象,但他们的子对象还是指向统一对象(引用)
在这里插入图片描述

2.3 深拷贝

b = copy.deepcopy(a): 深度拷贝, a 和 b 完全拷贝了父对象及其子对象,两者是完全独立的
在这里插入图片描述

3.第三个题目

g1 = 1
g2 = []
g3 = 3
print(id(g3))
def f(g3):
    print(id(g2),id(g3))
    g1 = 2
    g3 = 4
    print(id(g1),id(g3))
    g2.append(1)

f(g3)
print(g1, g2, g3)

结果是:
在这里插入图片描述
两个结论:
1.对于不可变对象,函数内部是可以读全局变量的,但是一旦全局变量出现在赋值表达式的左边,就被视为函数内部的新定义的一个局部变量,如果直接使用g1会提示g1未定义;但是对于可变对象,函数内部能拿到全局的可变对象的引用
2.对于函数的参数传递,也是引用传递,对g3赋值后,函数内部的g3就指向别的地址了,全局变量g3并未发生变化;对于可变参数的引用传递,函数内g2内部的值发生变化后,全局的g2也跟着发生了变化

《完》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值