继续打脸水货教程:关于可变对象与不可变对象

news2024/11/27 22:24:51

入门教程、案例源码、学习资料、读者群

请访问: python666.cn

大家好,欢迎来到 Crossin的编程教室 !

今天这篇我要继续来打脸互联网上各种以讹传讹的水货教程。

前阵子我们聊了下Python中有关函数参数传递以及变量赋值的一些内容:Python到底是引用传递还是值传递?网上大多数教程都讲错了

先简单回顾下前文要点:

1. Python 中的变量不是装有对象的“容器”,而是贴在对象上的“标签”。
c61c9daa873d6b2c924569bfb69ecfbe.jpeg

2. 参数传递相当于一次赋值:多贴了一个标签。

3. 至于在函数内部对参数的修改是否会影响到外部变量的值,取决于你怎样修改:如果是重新赋值就不会,如果是修改对象自身内容则会。

讲到这里就有个常被提及的概念:
可变对象不可变对象

在 Python 中,
可变对象包括 list、dict、set、自定义类型等;
不可变对象包括 int、float、bool、str、tuple 等。

不可变对象不允许对自身内容进行修改。很多教程里这么说:如果我们对一个不可变对象进行赋值,实际上是生成一个新对象,再让变量指向这个对象。哪怕这个对象简单到只是数字 0 和 1:

a = 0
print('a', id(a))
a = 1
print('a', id(a))

输出:

a 4463151440
a 4463151472

这句话是没错。但这个说法其实极具误导性!难道我给一个可变对象进行赋值,就不是生成一个新对象了吗?

a = [0]
print('a', id(a))
a = [1]
print('a', id(a))

输出:

a 140286304509768
a 140286304509832

这不是也变了嘛!只要是给变量赋一个新值,就会生成一个新对象。关于这点,我们稍后还会再说。

因为对象不可变,所以为了提高效率,Python 会使用一些公用的对象:

a = 1
print('a', id(a))
b = 1
print('b', id(b))
print(a == b)
print(a is b)
c = 'hello world'
print('c', id(c))
d = 'hello world'
print('d', id(d))
print(c == d)
print(c is d)

输出:

a 4423761776
b 4423761776
True
True
c 4430180912
d 4430180912
True
True

这里顺便提一下 is 这个操作符。它和 == 的区别在于:== 只判断“值”是不是相等,而 is 则判断是否为同一个对象,也就是地址一致。比如:

a = 2
b = 2.0
print(a == b)
print(a is b)

输出:

True
False

这里插一句,判断一个列表是否包含某一元素的 in 操作符,你觉得它是判断 == 还是 is?猜猜这个输出是什么:

print(1.0 in [1, 2, 3])

与不可变对象的区别在于,可变对象除了被赋值外,还可以对自身内容进行修改,如:

m = [1, 2, 3]
print('m', m, id(m))
m[1] = 4
print('m', m, id(m))
m.append(5)
print('m', m, id(m))

输出:

m [1, 2, 3] 4536815752
m [1, 4, 3] 4536815752
m [1, 4, 3, 5] 4536815752

可以看到,虽然 m 的值发生了变化,但是地址没变,还是原来那个 m。

上次我也说到,很多的教程都在用可变和不可变来谈论赋值和参数传递,我觉得这些作者是不是自己也没整明白。因为他们举例不可变对象时用的是赋值,而举例可变对象又用了 list 的索引、apeend 等方法,这根本是两码事。就像我前面写的,如果大家都是赋值,那么无论是否可变,效果都是一样的,都会生成一个新对象,而不会对原变量的值产生影响。

所以理解了 Python 的赋值原理,就明白这与是否可变无关。而可变对象与不可变对象本身的不同仅在于一个可以修改变量的值,而另一个不允许。

两者在功能上的还有个区别就是:不可变对象可以作为字典 dict 的键 key,而可变对象不行。比如 list 不能作为字典的键,但 tuple 可以。

另外,明白了可变与不可变的区别,一些方法的效果也就更容易理解了:

s = 'abc'
s2 = s.replace('b', 'd')
print('s', s)
print('s2', s2)
m = [1, 2, 3]
m2 = m.reverse()
print('m', m)
print('m2', m2)

输出:

s abc
s2 adc
m [3, 2, 1]
m2 None

因为 str 是不可变对象,所以它的方法如 replacestripupper 都不可能修改原对象,只会返回一个新对象,必须重新赋值才可以。而 list 是可变对象,它的方法如 reversesortappend,都是在原有对象上直接修改,无返回值。

不过,有个特殊情况需要注意:

m = [1, 2, 3]
print('m', m, id(m))
m += [4]
print('m', m, id(m))
m = m + [5]
print('m', m, id(m))

输出

m [1, 2, 3] 4494164104
m [1, 2, 3, 4] 4494164104
m [1, 2, 3, 4, 5] 4494181128

m = m +m += 虽然是一样的结果,但 m 指向的对象却发生了变化。原因在于,前者是做了赋值操作,而后者其实是调用的 __iadd__ 方法。

如果我们就是需要产生一个 list 对象的副本,可以通过 [:]

m = [1, 2, 3]
print('m', m, id(m))
n = m[:]
print('n', n, id(n))
n[1] = 4
print('m', m)
print('n', n)

这样对 n 的修改便不再会影响到 m,因为它们已不是同一个对象。

那么如果是这样呢:

m = [1, 2, [3]]
n = m[:]
n[1] = 4
n[2][0] = 5
print(m)

猜一猜 m 的结果是什么?欢迎在评论区说下你的答案。

然后再去 Python 里执行下看看输出,是不是和预期一样,想想为什么?这个牵涉到浅拷贝、深拷贝的概念,我们下次再聊。

感谢转发点赞的各位~


_往期文章推荐_

我用什么写Python?


如需了解付费精品课程教学答疑服务

请在Crossin的编程教室内回复: 666

d23cb431e6012bb23aaa90ae04f8e968.jpeg

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

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

相关文章

LeetCode0014.最长公共前缀 Go语言AC笔记

时间复杂度:O(n) 解题思路 纵向扫描法。先扫描所有字符串的第一个字符,如果都相同就再次扫描所有字符串的第二个字符,直到某一字符串被扫描完或者出现了不相同的字符,此时就返回该字符串该字符的前缀。 为了确定所有字符是否相同…

【flask】三种路由和各自的比较配置文件所有的字母必须大写if __name__的作用核心对象循环引用的几种解决方式--难

三种路由 方法1:装饰器 python C#, java 都可以用这种方式 from flask import Flask app Flask(__name__)app.route(/hello) def hello():return Hello world!app.run(debugTrue)方法2: 注册路由 php python from flask import Flask app Flask(__name__)//app…

Java IO流第一章

Java IO流第一章 (一)简介 本文主要是从最基础的BIO式通信开始介绍到NIO , AIO,读者可以清晰的了解到阻塞、同步、异步的现象、概念和特征以及优缺点。 通信技术整体解决的问题 局域网内的通信要求。多系统间的底层消息传递机制。高并发下…

如何自制云平台,并实现远程访问控制?

除了阿里、腾讯各种云,计算机大神们都想自己搭建IoT云平台。今天小编跟大家分享一种用UbuntuEMQXNode-RED方式自制IoT云平台的方法,并实现无公网IP随时访问远程数据! 第一步 Step1搭建EMQX服务器 1.搭建IoT平台需要一个服务器,这…

windows安装rocketmq

windows安装rocketmq 问题背景操作步骤Lyric: 请再给我 一个理由 问题背景 最近有使用rocketmq,为测试方便,在本地安装rocketmq 注意事项: 默认已安装java1.8,启动mq必须是1.8版本,我之前使用11版本&…

命令行 控制 易微联 wifi通断器

有个设备需要远程控制开关,最简单的方式就是通过一直在线运行的 Pi,进行命令行控制智能开关。 1、材料准备 找个最便宜的智能开关,话说易微联的做的真是便宜,销售量也很大。 这种 网上叫 Wifi通断器,或者智能开关&a…

使用ALLpairs完成正交表测试法练习题

该实验报告需要完成如下三个正交表测试法练习题 1、为了测试一个游戏软件的安装过程,需要考虑如下因素: (1) 操作系统: win2008、win7、win10、RedHat、Linux (2) 杀毒软件:瑞星、卡巴斯基、诺顿、江民、360 杀毒 (3) 数据库: oracle10g、SQLServer200…

五一劳动节前 特辑 ,路上那些车不能碰 你赔不起系列

相信明天大家4月29日都上了高速,都奔赴自己今年第一个想去的地方,那么上了高速,见的车辆就多了,哪些车辆我们要明白,尽量不要去碰,或者看见进行 技术性躲避,因为碰一下,半套房没了&a…

Pytorch2 如何通过算子融合和 CPU/GPU 代码生成加速深度学习

动动发财的小手,点个赞吧! PyTorch 中用于图形捕获、中间表示、运算符融合以及优化的 C 和 GPU 代码生成的深度学习编译器技术入门 计算机编程是神奇的。我们用人类可读的语言编写代码,就像变魔术一样,它通过硅晶体管转化为电流&a…

大二一个学期学这么点内容,没有概念,只有实操

如何查看所有的数据库: Show databases; 如何进入某个数据库: use xxx; 如何新进数据库: Create database jx; 如何删除数据库: Drop database jx; 如何查看所有的表格: Show tables; 如何创建数据表&#xf…

Segmentation of retinal vessels based on MRANet

随手把一篇论文的创新部分抽取出来 MLF 为了更好地聚合每一层的上采样特征信息和MSR块的信息,在解码路径中使用了MLF块,这允许最大限度地重用功能,从而减少细节的损失。MLF块的结构如图2所示。 如图2所示,有两种输入:input1和inp…

直接攻击,越狱攻击,道德攻击……这样做,ChatGPT 就会泄漏你的隐私

夕小瑶科技说 原创作者 | 小戏 大模型的出现让我们的隐私比以往任何时候都危险。 一个很直观的例子,在大模型向黑洞一样不断吞噬现有网络中的文本数据之时,伴随着模型训练的文本数量从 GPT-2 的 40GB 文本到 GPT-3 的 45TB 文本,我们可以非常…

郑哲:学习、应用初探与探索创新 | 提升之路系列(四)

导读 为了发挥清华大学多学科优势,搭建跨学科交叉融合平台,创新跨学科交叉培养模式,培养具有大数据思维和应用创新的“π”型人才,由清华大学研究生院、清华大学大数据研究中心及相关院系共同设计组织的“清华大学大数据能力提升项…

python中snap-stanford指导手册(主要用于做图网络)

文章目录 RequirementSnap操作手册Basic TypesVector TypesHash Table TypesPair TypesGraph and Networks Types(graph和network类型)Node and Edge Operation Requirement 需要提前安装用于操作图网络的snap库,这个库中有很多现成的图数据…

物联网平台:一文读懂什么是物模型

文章目录 一、什么是物模型二、标准参数(1)标准参数的意义 三、物模型字段详细说明(1)物模型的每个属性包含以下字段(2)物模型的每个方法包含以下字段(3)物模型的每个事件包含以下字…

【Python】【进阶篇】15、如何启动Django项目详解

目录 如何启动Django项目详解1. 启动项目并实现访问1) 启动项目命令介绍2) manage.py文件子命令 如何启动Django项目详解 我们使用 django-admin 命令成功创建项目后,我们要如何启动这个项目呢?本节的学习目标是能够通过本地回送地址 127.0.0.1 成功访问…

第十一章 Transform组件(上)

本章节我们介绍Transform类,它是一个组件,每一个游戏对象有拥有该组件。因此,它值得我们重点介绍一下。Transform代表了游戏对象的世界变换,也就是移动,选择和缩放。 首先,我们先介绍它的属性(…

Linux Ansible角色介绍

目录 角色的基础结构 角色来源与应用 Galaxy角色 系统角色 自定义角色 角色(roles)用于层次化、结构化地组织playbookroles通过标准化目录结构来装载变量文件、tasks(模块任务)、handlers(处理程序)、…

标准ACL配置

标准ACL配置 【实验目的】 掌握标准ACL的配置。 验证配置。 【实验拓扑】 实验拓扑如图1所示。 图1 实验拓扑 设备参数如表所示。 表1 设备参数表 设备 接口 IP地址 子网掩码 默认网关 R1 S0/3/0 192.168.1.1 255.255.255.252 N/A Gi0/0/0 192.168.2.1 255.…

大数据分析利器之Power BI,你是否已经掌握?(文末送书)

🤵‍♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞&#x1f4…