深入浅出讲解Python中的可变类型与不可变类型,以及赋值,浅拷贝与深拷贝的区别

news2024/9/20 18:54:36

文章目录

    • 1、不可变数据类型
    • 2、可变数据类型
    • 3、赋值,浅拷贝与深拷贝
      • 3.1 赋值操作符 =
      • 3.2 浅拷贝copy()
      • 3.3 深拷贝copy()
    • 小结

在Python中,数据类型主要分为可变数据类型和不可变数据类型。主要的区别在于可变数据类型的值可以改变,而不可变数据类型的值 一旦创建就不能更改。

在这里插入图片描述
在实际开发过程中,很多时候由于对可变数据集类型与不可变数据类型的疏忽也会导致一些较难排查的bug。

所以这里一个关键的点在于,不可变数据类型在变量创建了之后,这个值就存在了这个地址块中,就不能被改变了,你即使再给同一个变量更新值,那这个值也是重新开辟了一个内存空间存放地址。

不可变数据类型

  • 数值类型:int, float, complex, bool
  • 字符串类型:str
  • 元组:tuple

可变数据类型

  • 列表:list
  • 字典:dict
  • 集合:set

1、不可变数据类型

我们通过输出一部分例子来观察不可变数据类型

# 数字
x = 10
print(id(x))  # 输出x的内存地址
x = 20
print(id(x))  # 输出新的x的内存地址

# 字符串
s = 'hello'
print(id(s))
s = 'world'
print(id(s))

# 元组
t = (1, 2, 3)
print(id(t))
t = (4, 5, 6)
print(id(t))

大家可以执行上面这段代码,会发现每次的值都会是不一样的。这就是我们说的不可变数据类型


这个时候就出现了另一个问题,此时我的变量x获得了一个新的地址,原来的那个地址怎么办呢?
在Python中,每当我们创建一个新的对象(比如一个数字或者字符串),Python就会在内存中为这个对象分配一块新的地址。当我们更改变量x的值时,实际上Python会在内存中为新的值(比如数字20)分配一块新的地址,并将变量x指向这个新的地址。此时,变量x不再指向原来的地址(数字10的地址)。

至于原来的内存地址(存放数字10的那块内存)是否还在,这取决于是否还有其他变量在引用这块内存。如果还有其他变量引用,那么这块内存就会被保留;如果没有其他变量引用,那么Python的垃圾回收机制将会自动回收这块内存,释放内存资源。所以在你的例子中,如果没有其他变量引用数字10,那么数字10所在的内存就会被垃圾回收。这也是python垃圾回收中,我们通常所说的引用-计数原理。

id(x):内存地址A
id(x):内存地址B
没有引用
有引用
创建变量x, x = 10
内存地址A中的值: 10
更新变量x的值, x = 20
内存地址B中的值: 20
检查内存地址A是否还有引用
内存地址A被垃圾回收
内存地址A保持

2、可变数据类型

同样,我们也通过一些例子来观察

id(lst):内存地址A
id(lst):内存地址A
创建变量lst, lst = [1, 2, 3]
内存地址A中的值: [1, 2, 3]
更新变量lst的值, lst.append(4)
内存地址A中的值: [1, 2, 3, 4]
# 列表
lst = [1, 2, 3]
print(id(lst))
lst.append(4)
print(id(lst))

# 字典
d = {'a': 1, 'b': 2}
print(id(d))
d['c'] = 3
print(id(d))

# 集合
s = {1, 2, 3}
print(id(s))
s.add(4)
print(id(s))

在上述例子中,当我们改变可变数据类型的值时,其内存地址保持不变,这说明我们在原地修改了对象的值,而不是创建了新的对象。

3、赋值,浅拷贝与深拷贝

在Python中,=,copy()和deepcopy()都是用来复制对象的方法,但它们在处理可变数据类型和不可变数据类型时的行为是不同的。

3.1 赋值操作符 =

=:赋值操作符,它只是创建了一个新的变量,这个变量和原变量指向同一个对象。无论是可变数据类型还是不可变数据类型,都是如此。

# 对于不可变数据类型
x = 10
y = x
y = 20
print(x)  # 输出10

# 对于可变数据类型
lst1 = [1, 2, 3]
lst2 = lst1
lst2.append(4)
print(lst1)  # 输出[1, 2, 3, 4]

3.2 浅拷贝copy()

对于不可变数据类型,由于它们的值不能更改,所以浅拷贝和赋值没有区别;
对于可变数据类型,浅拷贝会创建一个新的对象,但如果对象中还包含可变数据类型的元素,这些元素仍然是指向原对象。这里可以着重看下我下面写的关于可变数据类型两种情况下的例子

# 对于不可变数据类型
import copy
x = 10
y = copy.copy(x)
y = 20
print(x)  # 输出10

# 对于可变数据类型
lst1 = [1, 2, 3]
lst2 = copy.copy(lst1)
lst2.append(4)
print(lst1)  # 输出[1, 2, 3]

lst3 = [1, 2, [3, 4]]
lst4 = copy.copy(lst3)
lst4[2].append(5)
print(lst3)  # 输出[1, 2, [3, 4, 5]]

3.3 深拷贝copy()

深拷贝,无论是可变数据类型还是不可变数据类型,它都会创建一个新的对象,并且会递归地拷贝对象中的元素。

# 对于不可变数据类型
import copy
x = 10
y = copy.deepcopy(x)
y = 20
print(x)  # 输出10

# 对于可变数据类型
lst1 = [1, 2, 3]
lst2 = copy.deepcopy(lst1)
lst2.append(4)
print(lst1)  # 输出[1, 2, 3]

lst3 = [1, 2, [3, 4]]
lst4 = copy.deepcopy(lst3)
lst4[2].append(5)
print(lst3)  # 输出[1, 2, [3, 4]]

因此,=copy()deepcopy()在处理可变数据类型和不可变数据类型时的主要区别在于:=只是创建一个新的变量,而不创建新的对象;copy()会创建一个新的对象,但不会递归地拷贝对象中的元素;deepcopy()会创建一个新的对象,并且会递归地拷贝对象中的元素。

小结

理解Python中的可变与不可变数据类型,对于理解Python中的变量赋值、函数参数传递、深浅拷贝等概念非常重要。

如果需要更多Python源码的,可以参考以下小程序"编程树"中获得大量的python项目源码。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/733688.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【网络系统集成】路由器实验

1.实验名称:路由器RIP协议配置 2.实验目的 在PacketTracer中进行模拟实验,配置RIP协议,验证RIP协议更新时间及路由状态变化,加深对路由器RIP协议相关知识的理解与掌握。 3.实验内容 (1)拓扑结构图 (2)ip地址分配与端口分配

Mybatis基础总结1

Mybatis快速入门 一.Mybatis快速入门1.1 框架介绍1.2 ORM介绍1.3 原始jdbc操作(查询数据)1.4原始jdbc操作(插入数据)1.5 原始jdbc操作的分析1.6 什么是Mybatis1.7 Mybatis的快速入门1.7.1 环境搭建1.7.2编写测试代码 1.8 知识小结…

Linux进程调度

转自:深入理解Linux进程调度(0.4)_进程调度 城_城中之城的博客-CSDN博客 一、进程调度概览 进程调度是操作系统最重要的内容之一,也是学习操作系统的重点和难点。关于进程本身的实现和管理请参看《深入理解Linux进程管理》。关于进程调度,我…

阿里云ECS服务器架构X86计算_ARM_GPU/FPGA_裸金属_超级计算集群

阿里云服务器架构有什么区别?X86计算、ARM计算、GPU/FPGA/ASIC、弹性裸金属服务器、超级计算集群有什么区别?阿里云服务器网分享云服务器ECS架构详细说明: 目录 阿里云服务器ECS架构说明 X86计算 ARM计算 GPU/FPGA/ASIC 弹性裸金属服务…

mysql单表查询,排序,分组查询,运算符,select,order by,group by

CREATE TABLE emp (empno int(4) NOT NULL, --员工编号ename varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,--员工名字job varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,--员工工作mgr int(4) NULL DEFAULT NU…

json 解析chrome浏览器插件json-handle

插件地址 非常好用,平常工作中需要经常查看对象属性,展开的时候往往都是很长的数据,有了这个大大提升效率了

云计算值得学习吗

云计算值得学习吗 云计算作为一项重要的技术和商业模式,未来的发展前景非常广阔。随着企业和个人对云计算需求的增长,以及新兴技术的不断突破和创新,云计算将继续引领科技进步和社会发展,并为用户带来更多的便利和创新&#xff0…

项目配置日志的打印目录,输出日志

最近的项目需要在服务器上跑&#xff0c;配个日志方便查看。简单记录一下&#xff0c; resources下新增日志配置的xml文件&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <configuration scan"true" scanPeriod"10 seco…

从零开始 Spring Boot 67:JPA 中的惰性元素

从零开始 Spring Boot 67&#xff1a;JPA 中的惰性元素 图源&#xff1a;简书 (jianshu.com) 惰性加载带来的问题 在实体类之间建立关系时&#xff0c;可以选择“惰性加载”&#xff0c;比如&#xff1a; Entity public class Student {// ...OneToMany(mappedBy "stu…

基于springboot,vue网上订餐系统

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 前端技术 &#xff1a;VueElementUI 服务端技术&#xff1a;springbootmybatisredis 本系统分用户前台和管理后台两部分&#xff0c;项…

【Kafka】Kafka的Broker概述

【Kafka】Kafka的Broker概述 文章目录 【Kafka】Kafka的Broker概述1. Broker的工作流程1.1 Zookeeper存储的Kafka信息1.2 Broker 总体工作流程1.3 Broker重要参数 2. 节点服役和退役2.1 服役新节点2.2 退役旧节点 3. Kafka副本3.1 副本信息3.2 Leader选举流程3.3 Leader 和 Fol…

【成都】EFDC建模方法、SWAT模型高阶研修

EFDC建模方法及在地表水环境评价、水源地划分、排污口论证应用 为了定量地描述地表水环境质量与污染排放之间的动态关系&#xff0c;EFDC、MIKE、Delft3D、Qual2K等数值模型被广泛应用在环境、水务、海洋等多个领域。Environmental Fluid Dynamics Code&#xff08;EFDC&#…

[NISACTF 2022]checkin

[NISACTF 2022]checkin 直接给了源码&#xff0c;乍一看非常的简单&#xff0c;但是这题有坑。其实看注释颜色不一样&#xff0c;也能发现不对劲了。 贴一个payload&#xff0c;?ahahahahajitanglailo&%E2%80%AE%E2%81%A6Ugeiwo%E2%81%A9%E2%81%A6cuishiyuan%E2%80%AE%E2…

ARM异常处理详解

前言&#xff1a; 学习一门处理器最重要的就是掌握该处理器的指令集和异常处理。 异常概念&#xff1a; 处理器在正常执行程序时可能会遇到一些不正常的事件发生&#xff0c;这时处理器就要将当前的程序暂停下来转去处理这个异常的事件&#xff0c;异常处理后再返回到被异常打…

需求分析引言:架构漫谈(五)架构师成长之路

我研发领域也从事了一些年&#xff0c;期间也做过一些架构设计工作&#xff0c;包括C#单体转型为Java微服务、Python单体转型为Java微服务等&#xff0c; 也尝试着从自己的经验角度&#xff0c;来汇总一些知识点&#xff0c;同时描述一下如何成长为一个合格的软件架构师&#x…

权限管理系统后端实现1-SpringSecurity执行原理概述

spring security的简单原理&#xff1a; SpringSecurity有很多很多的拦截器&#xff0c;在执行流程里面主要有两个核心的拦截器 1&#xff0c;登陆验证拦截器AuthenticationProcessingFilter 2&#xff0c;资源管理拦截器AbstractSecurityInterceptor 但拦截器里面的实现需要…

IDEA+Spring Boot + MyBatis + Layui+Mysql垃圾回收管理系统源码

IDEASpring Boot MyBatis LayuiMysql垃圾回收管理系统源码 一、系统介绍1.环境配置 二、系统展示1. 管理员登录2.垃圾回收管理3.添加需要回收的垃圾4.垃圾去向管理5.申请需要打包运出的垃圾6.系统公告管理7.个人信息管理8.修改密码 三、部分代码UserMapper.javaUserControlle…

Python的网络爬虫框架-网络爬虫常用框架

Python的网络爬虫框架-网络爬虫常用框架 一、前言二、引言三、Scrapy 爬虫框架四、Crawley 爬虫框架五、PySpider 爬虫框架 一、前言 个人主页: ζ小菜鸡大家好我是ζ小菜鸡&#xff0c;让我们一起来了解Python的网络爬虫框架-网络爬虫常用框架如果文章对你有帮助、欢迎关注、点…

Redis缓存同步1-策略介绍

缓存数据同步策略示意图 在大多数情况下&#xff0c;我们通过浏览器查询到的数据都是缓存数据&#xff0c;如果缓存数据与数据库的数据存在较大差异的话&#xff0c;可能会产生比较严重的后果的。所以&#xff0c;我们应该也必须保证数据库数据、缓存数据的一致性&#xff0c;…

基于simulink使用颜色识别来进行道路跟踪(附源码)

一、前言 此示例演示如何使用颜色信息来检测和跟踪在可能不存在车道标记的主要住宅环境中设置的道路边缘。基于颜色的跟踪示例说明了如何使用色彩空间转换块、霍夫变换块和卡尔曼滤波器块来检测和跟踪使用色调和饱和度的信息。 二、模型 下图显示了基于颜色的道路跟踪模型&a…