Python之可变对象和不可变对象

Python之可变对象和不可变对象

  • 可变对象(mutable):对象本身的值可以改变,即改变对象内部的值的 时候,这个对象的id不会发生变化

  • 不可变对象(immutable):对象本身的值不能被修改,即改变对象内部的值的 时候,这个对象的id会发生变化

本章主要探讨(不)可变对象值一样id的变化

测试环境为3.9

  1. 可变对象
    可变对象包括:list(列表)、dict(字典)、set(集合)
>>> #以list为例子
>>> a_list=[1,2,3]
>>> id(a_list)         #输出:2961286586688
>>> a_list.append(4)   
>>> #对可变数据类型的操作不能是直接进行新的赋值操作,比如说a=[1,2,3,4,5,6,7],这样的操作就不是改变值了,而是新建了一个新的对象,这里的可变只是对于类似于append、+=等这种操作。
>>> id(a_list)         #输出:2961286586688
>>> #以list为例子
>>> a_list=[1,2,3]
>>> b_list=[1,2,3]
>>> id(a_list),id(b_list)   #输出:2339722453440 2339719495616
  1. 不可变对象
    不可变对象包括:int(整型)、float(浮点型)、str(字符串)、bool(布尔)、complex(复数)、truple(元组)
>>> a=1
>>> id(a)   #输出:2350887299376
>>> a=2
>>> id(a)   #输出:2350887299408
>>> #并不改变原始对象的值,只是创建一个新对象,并指向该变量,原始对象让Python的GC回收
  • int型
>>> #int值比较小时,值一样的变量id就一样,值变化id就变化。
>>> a=1
>>> b=1
>>> a is b   #输出:True
>>> #int值比较大时,值一样的变量id也不一样,值变化id就变化。
>>> a=257
>>> b=257
>>> a is b   #输出:False

该情况是在cmd运行,较小的整数会很频繁的被使用,Python为了优化速度,使用了小整数对象池,避免为整数频繁申请和销毁内存空间。
Python对小整数的定义是 [-5, 256] 这些整数对象是提前建立好的,不会被垃圾回收。
在一个 Python 的程序中,无论这个整数处于LEGB中的哪个位置,所有位于这个范围内的整数使用的都是同一个对象。
当在Python的IDLE运行下,情况会有所不同。因为它使用的是大整数对象池。
在终端中,每次执行一次,所以每次大整数都重新创建。而在IDLE中,每次运行是所有代码都加载都内存中,属于一个整体,所以这个时候会有一个大整数对象池,即处于一个代码块的大整数是同一个对象。

  • str型
>>> a="hello"
>>> b="hello"
>>> a is b            #输出:True
>>> a="hello world"
>>> b="hello world"   
>>> a is b            #输出:False
>>>> a="12"
>>> b="12"
>>> a is b            #输出:True
>>> a="1 2"
>>> b="1 2"
>>> a is b            #输出:False

对于str型,Python采用intern机制。单词类型的str由于被重复使用的概率比较大,所以在python中为单词类型的str做了一个缓存。
也就是说如果是单词类型的str,会被存储到一个字典(dict)中,字典的内容是字符串为key,地址为value。当有一个字符串需要创建,就先去访问这个字典,如果存在则返回字典中字符串的地址,如果不存在,则返回新创建的地址,并将这个字符串添加进入字典。
intern机制处理空格一个单词的复用机会大,所以创建一次,有空格创建多次,但是字符串长度大于20,就不是创建一次了。
需要强调的是终端与IDLE的处理情况仍不相同,有兴趣的可自行实验

https://www.jb51.net/article/183220.htm这篇帖子中还探讨了一个有趣的现象,与Python编译机制有关,欢迎大家拜读

  • float型
>>> a=1.1
>>> b=1.1
>>> a is b   #输出:False

对于float类型的使用自然没有int那么频繁,并且float类型也不好定义哪些常用,也就没有池子给到这个类型,所以每次重新创建即可
truple类型也与float类型相似

参考:https://www.cnblogs.com/shiyublog/p/10809953.html
https://www.jianshu.com/p/b3157c9751d0

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值