python:可变类型与不可变类型

python:可变类型与不可变类型

一、引用变量与变量在存储的存储形式

image-20230913160748640

在python有个id()方法,可以获取某个变量指向的内存地址

num1 = 10  # num1实际储存在栈内存中,当调用num1时通过内存地址引用储存在数据区中的10

# 如果把num1的值赋予num2,两者是什么关系呢
num2 = num1
print(num1, num2)
print(id(num1), id(num2))  # 会得到相同的内存地址,两者对数字10都是引用关系

# 在赋值之后,我们改变num1的值,num2是否会受到影响?
num1 = 100
print(id(num1))  # 140717001506144
print(id(num2))  # 140717001509024

# 结论:num2没有被影响,因为num1与num2都是数值类型(不可变类型),一个值的改变不会影响另一个值
# 不可变类型:内存地址一旦固定,其值就没有办法发生改变了,比如这块地址原来存放了10,想把它设置为100,不行,因为这块地址无法调整。重新开辟一块新的内存空间存储100,将内存地址赋予num1(num1与num2指向两块不同的内存地址,所以两者不会互相影响)

image-20230913161354560

  • 数值类型是不可变数据类型,改变其值,其内存地址也会发生改变(重新开辟空间,保存新的数据,变量指向新的数据内存地址)

image-20230913162544319

二、不可变数据类型

如上图所示:

不可变数据类型在第一次声明赋值声明的时候, 会在内存中开辟一块空间, 用来存放这个变量被赋的值, 而这个变量实际上存储的, 并不是被赋予的这个值, 而是存放这个值所在空间的内存地址, 通过这个地址, 变量就可以在内存中取出数据了. 所谓不可变就是说, 我们不能改变这个数据在内存中的值, 所以当我们改变这个变量的赋值时, 只是在内存中重新开辟了一块空间, 将这一条新的数据存放在这一个新的内存地址里, 而原来的那个变量就不在引用原数据的内存地址而转为引用新数据的内存地址了

不可变数据类型:数值型,布尔类型,字符串类型,元组类型
  • 不可变类型:内存地址一旦固定,其值无法改变的数据类型。

三、可变数据类型:

结合不可变数据类型,可变数据类型就很好理解来,可变数据类型是指变量所指向的内存地址处的值是可以被改变的。

可变数据类型:列表,字典,集合
  • 可变类型:内存地址一旦固定,其值可以改变的类型。
list1 = [1, 2, 3]
print(id(list1))  # 

# 向列表中追加一个元素,改变列表的值
list1.append(4)
print(id(list1))  # 

image-20230913173904230

追加元素,改变列表的值其内存地址没有发生改变:
image-20230913174052061

从另外一个角度来看:

可变类型:当该数据类型的对应变量的值发生了改变,那么它对应的内存地址也会发生改变,对于这种数据类型,就称不可变数据类型。

可变数据类型:当该数据类型的对应变量的值发生了改变,那么它对应的内存地址不发生改变,对于这种数据类型,就称可变数据类型。

四、可变与不可类型对传参的影响

案例1:可变数据类型

def func1(list1):
    # 相当于 list1 = list2   
    list1.append('赵六')
    return list1


list2 = ['张三', '李四', '王五']

func1(list2)
print(list2)  # ['张三', '李四', '王五', '赵六']
  • list是可变数据类型,list1与list2指向同一块内存地址,可以改变列表中的值

案例2:不可变数据类型

def func2(num1):
    # 相当于 num1 = num2
    num1 += 1
    return num1


num2 = 10
func2(num2)
print(num2)  # 10

image-20230913192829540

  • 将num2 赋值给num1之后,相当于num1与num2指向同一块内存地址,当实现num1的值改变时,因为num是不可改变类型,只能重新开辟一块新的内存空间保存11,并将地址赋予num1

五、扩展:元组拆包

1、什么是拆包?

简单来说就是将元组中的数据一个一个拆解出来的过程,被称之为拆包操作。

2、基本语法

tuple1 = (10, 20)
# 拆包
num1 , num2 = tuple1

# 以上代码可以简写
num1 , num2 = (10, 20)

# 还可以进一步简写
num1 , num2 = 10 , 20
  • 左边变量的数量要与元组的数据的数量一致

3、元组拆包的典型案例

a = '可乐'
b = '牛奶'

# 之前实现交换都是引用第三变量temp
a , b = b , a

print(a) # 牛奶
print(b) # 可乐
posted @   七落安歌  阅读(152)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示