课时13:可变对象

简介: 可变对象是指其值可以在创建后被修改的对象。每个对象包含三个属性:Id(标识)、Type(类型)和Value(值)。其中,只有Value是可变的。例如,列表是典型的可变对象,可以通过索引修改其元素。通过代码演示和图示,本文详细解释了如何区分修改对象与修改变量的区别及其影响。修改对象时,所有指向该对象的变量都会受到影响;而修改变量则仅影响该变量本身,不会影响其他变量。总结来说,赋值操作通常修改变量,而通过索引或方法修改内容的操作则修改对象。

可变对象

 

摘要 

1.可变对象的定义与组成

2.列表演示

3.列表中的对象与变量

 

01.可变对象的定义与组成

1.1可变对象的定义与组成

可变对象指的是对象的值可变。

每个对象中都保存了三个数据:Id(标识)Type(类型)Value(值)

先回顾一下之前画的图:

image.png

图中 Id Type 的对象是不可变的,唯一能改变的是 Value,但是仅限于是可变对象。像数字、字符串、Bool 值等的 Value 值是不可变的,但是可变对象是可以改变的,比如列表就是一个可变对象。

 

02.列表演示

 

2.1列表演示

列表是一个可变对象。

a=[1,2,3]

例如,a=[1,2,3]用图体现出来,如下:

a 是变量,[1,2,3]是 a 的对象,对象需要在内存里专门开辟出一块区域去保存这个对象。

先插入一块儿区域,在该区域里设置三个数据,IdTypeValue

Id 假设为0x111Type 类型为 Class List,因为是一个列表。

Value 为[1,2,3]。如下图:

image.png

这里 Value 属于简写了,若详细去写,结构会稍复杂一些。先用这种结构方式来变现一下。变量 a 里有保存它的 Id 地址,所以第一个值是 0x111,就相当于变量里有一个指针指向内存对象。如图:

image.png

图中 Value 的值是可变的。

 

03.列表中的对象与变量

 

3.1修改对象

为体现出可变对象,现在做一个代码演示一下:

a=[1,2,3]
a[0]=10

这个时候再执行,如下:

image.png

再次用图演示,这里把索引为 0 的值改为了 10 ,这里通过变量找到对象修改了对象当中索引为 0 的那个值,所以这里改的是 Value=[10,2,3]这个位置。因为对象 Value 值被改变了,所以这就是可变对象。

image.png

可变对象指的是对象里的 Value 可以被改变。

 

3.2修改变量

如果直接写:

a=[4,5,6]
a
[4,5,6]

这两种方式是不一样的,因为

image.png

这种方式是在修改对象,而

image.png

这种方式是直接改这个变量。

如果写的是 a=[4,5,6],实际上这个是一个新的列表,既然是新的列表那么就要创建新的对象。那么在内存里就应该这样体现的,新的对象改一个新的地址,Id为0x211,那么 a 里面的值变为 0x211,如图:

image.png

这个 a=[4,5,6]操作并没有对 a=[10,2,3]产生影响,因为现在是创立的一个新的对象,然后赋值给a。

 

3.3改对像和改变量的作用

a[0]= 10(改对象)

这个操作是在通过变量去修改对象的值所以这种操作不会改变变量所指向的对象当去修改对象时,如果有其他变量也指向了该对象,则修改也会在其他的变量中体现

a=[456](改变量 )

这个操作是在给变量重新赋值这种操作会改变变量所指向的对象

为一个变量重新赋值时,不会影响其他的变量

 

3.4改对像和改变量的区别

接下来演示二者区别:

#可变对象
a = [1,2,3]
print( ' 修改前: ', a  ,id(a))

紧接着执行,如图:

image.png

接下来继续添加:

# 通过索引修改列表

a[0]= 10

print( ' 修改: 'a  id(a))

再次执行如图:

image.png

这时会发现 Id 并没有改变。只是对象里的值变了,对象不变。所以通过索引修改的,它是在修改对象。

#为变量重新赋值
a=[4,5,6]
print( ' 修改后: ', a  ,id(a))

image.png

执行后发现 Id 改变,值发生改变,但生成的是一个新的对象。

所以,改对象的时候,变量中保存的内存地址是不会变的。而在改变量的时候它实际上是给变量重新赋值了。

 

3.5改对象与改变量的影响

l 用代码演示

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

编译执行后,如图:

image.png

接下来添加一步,b[0]=10,通过索引把 0 改成 10,如下:

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

编译执行后,如图:

image.png

结论:当我们去修改对象时,如果有其他变量也指向了该对象,则修改也会在其他的变量中体现

l 用图演示

为更好的理解这个结论,可以通过下面的图来体现:

当a=[1,2,3],b=a时,ab指向的是同一个对象。

现在通过索引 0 来修改对象值,修改后,a b 还是同一个指向。

image.png

接下来直接将 b=[10,2,3],如下所示:

a=[1,2,3]
b=a
b=[10,2,3]
print(“a”, a, id(a))
print(“b”, b, id(b))

这个时候 a 不变,因为在给变量重新赋值的时候,是不会影响其他变量的。

将上述代码编译执行后,如图:

image.png

这时的 Id 不一样了。

结论:为一个变量重新赋值时,不会影响其他的变量。可以通过下面的图来体现:

当 a=[123],b=ab=[1023]时,说明 b=[1023]是一个新的列表,那么新的列表就意味着要创建一个新的对象。

image.png

这个操作不会对 a 有任何影响,因为我们是在给 b 变量重新赋值,对 a 没有影响。如果改对象的时候就会影响了,但是现在改对象影响不了,因为现在是属于两个对象了。

所以,改对象的时候如果别的变量也指向这个对象,会对那些变量也产生影响。而改变量是只影响本身,不会影响到其他变量。

 

3.6如何区别是改对象、改变量

一般只有在为变量赋值时才是修改变量,其余的都是修改对象

例如:一般看到(a=…)之类的是改变量,而(a[..]=…)之类的大部分都是改对象。

相关文章
|
Arthas 监控 Java
Java 诊断利器 Arthas使用
Java 诊断利器 Arthas使用
3713 0
|
XML Java Android开发
Android Studio App开发中使用录音机、MediaRecorder录制音频和MediaPlayer播放音频讲解及实战(附源码)
Android Studio App开发中使用录音机、MediaRecorder录制音频和MediaPlayer播放音频讲解及实战(附源码)
964 0
|
8月前
|
存储 索引 容器
课时15:字典的介绍
字典是一种映射数据结构,与列表不同,它通过键值对存储对象,查询效率更高。字典的每个元素由唯一键(Key)和对应的值(Value)组成,称为键值对。键必须是不可变对象(如字符串、数字),且不能重复。字典适合快速查找特定信息,而列表则按索引访问元素,查询性能较低。以下是创建字典及获取值的示例代码: 字典提供了一种高效、灵活的方式来组织和访问数据。
|
存储 关系型数据库 MySQL
智能调度、秒级弹性|一文带你探索Compaction Service的进化之路
ADB MySQL的Compaction Service功能通过将Compaction任务从存储节点解耦至独立的弹性资源池执行,解决了资源隔离性弱、并发度低等问题,实现了资源消耗降低50%,任务执行时间平均减少40%,并支持按量付费,提升了系统的稳定性和成本效益。
|
10月前
|
负载均衡 算法
架构学习:7种负载均衡算法策略
四层负载均衡包括数据链路层、网络层和应用层负载均衡。数据链路层通过修改MAC地址转发帧;网络层通过改变IP地址实现数据包转发;应用层有多种策略,如轮循、权重轮循、随机、权重随机、一致性哈希、响应速度和最少连接数均衡,确保请求合理分配到服务器,提升性能与稳定性。
2221 11
架构学习:7种负载均衡算法策略
|
消息中间件 负载均衡 中间件
【Alibaba中间件技术系列】「RocketMQ技术专题」让我们一起探索一下DefaultMQPullConsumer的实现原理及源码分析
【Alibaba中间件技术系列】「RocketMQ技术专题」让我们一起探索一下DefaultMQPullConsumer的实现原理及源码分析
355 84
【Alibaba中间件技术系列】「RocketMQ技术专题」让我们一起探索一下DefaultMQPullConsumer的实现原理及源码分析
|
Java 应用服务中间件 Linux
【Docker容器化技术】docker安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库
本文主要讲解了Docker的安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库以及Docker容器虚拟化与传统虚拟机比较。
13487 38
【Docker容器化技术】docker安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库
|
关系型数据库 MySQL Java
实时计算 Flink版产品使用问题之如何提高Flink从MySQL读取数据的速度并减少延迟
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
运维 监控 Devops
DevOps实践:从理论到落地的旅程
在软件开发和运维日益融合的今天,DevOps已不仅仅是一个流行词汇。它代表了一种文化和实践的转变,旨在打破部门间的壁垒,加速产品从构思到市场的流程。本文将带你了解DevOps的核心理念,并通过实际案例展示如何将这些理念应用到日常工作中,实现高效协作和持续改进。无论你是DevOps新手还是资深专家,这篇文章都将为你提供新的视角和实用的技巧。
|
JavaScript Java 测试技术
基于SpringBoot+Vue的外卖平台系统的详细设计和实现
基于SpringBoot+Vue的外卖平台系统的详细设计和实现
348 4