Python番外篇:变量是盒子还是标签

news2024/9/20 5:46:20

引言

前面通过几十篇文章,大概把Python的一些比较实用的基础做了一些介绍,学会这些,基本能应付日常的小的需求开发了,写一些小工具,提高工作的处理效率。

接下来,准备开始进入一个新的篇章,也就是Python的面向对象了。

但是,在开始介绍Python面向对象之前,还是需要对变量这个从开始学一直到每次写代码都要用到的概念,再稍微唠叨一番。

因为,很多编程自学者,哪怕写了挺多的代码了,其实对变量还是一知半解的状态。

变量的盒子比喻

有些教材在介绍变量是,经常将变量比喻为盒子,变量的值,为盒子中所保存的内容。这对于静态语言中的普通变量来说,是合适的。但是,对理解面向对象语言中的引用型变量,会造成理解上的困扰。

如果变量是盒子,那以下的代码是不可解释的:

# 如果变量是盒子,现在有一个盒子叫a,这个盒子里面装着[1, 2, 3]
a = [1, 2, 3]
# 有一个新的盒子,叫b,这个盒子里面也装着[1, 2, 3]
b = a
# 目前来说,从print输出来看,盒子的比喻都是没有问题的
print(a)
print(b)
# 但是,当我们修改了b[0]时,盒子的比喻无法解释了
b[0] = 100
print(b)
# 我们只是修改了b盒子的元素,为什么a盒子的也变了
print(a)

执行结果:

02f35c4b645ff8ff0c42b3cb993e2084.jpeg

变量的标签比喻

既然变量是盒子的比喻,解释不通了,我们对于变量的理解,必须换一个思路去理解。

在Python中一切皆是对象,变量是跟对象进行绑定的,这种绑定关系又是可以改变的,也许把变量理解成贴在对象上的便签纸,也许更加容易理解。

e0f74cfce290e351ec770355704baadd.jpeg

注:标签比喻及对应的图片来源于《流畅的Python》。

垃圾就该待在垃圾箱里

我们在Python代码中,使用任何对象,都是通过变量来实现的。一个对象上有一个变量与之对应,也就是贴了一个标签,在Python中叫做存在一个对该对象的引用。有多个变量与这同一个对象产生了对应,也就是有多个对该对象的引用。

那么,问题来了,如果一个内存中的对象上没有贴任何标签,也就是没有任何变量与之对应,也就是对该对象的引用数为0,那么这个对象我们可以使用吗?

答案显然是否定的,因为我们根本无法找到这个对象,那么这个对象在内存中,占用着存储空间,却没有任何用,那就是内存垃圾了,垃圾就应该待在垃圾箱里。

所以,最基础、最朴素的内存回收就是基于对象的引用计数实现的,当一个对象的引用计数为0,则这个对象被标记为垃圾,在特定的时机,会出发垃圾回收机制,将之从内存中释放。

在Python中,可以通过sys.getrefcount()函数,获取一个对象的引用,但是,需要注意的是:getrefcount()函数返回的计数会比实际引用计数多一个,因为它包含了作为参数传递给getrefcount()函数时创建的临时引用。

import sys
a = [1, 2, 3]
print(sys.getrefcount(a))
b = a
print(sys.getrefcount(a))
c = a
print(sys.getrefcount(a))
# del操作,并不是删除对象,而是解除变量对对象的引用
del c
print(sys.getrefcount(a))
# 重新赋值操作,也会解除对原对象的引用
b = 123
print(sys.getrefcount(a))

执行结果:

dfa11f99aa9ef3c5b98f41f59752815b.jpeg

通过引用计数,我们可以知道,此前对del操作的理解,其实可能也是有些偏差的。

del操作,只是解除该变量与某个对象对应的引用关系,对象的引用计数会减少,但并不是字面意思上的删除对象。即使当前变量是对某个对象的最后一个引用了,del之后引用计数为0了,也不是立马进行垃圾回收。而是,在恰当的时机,比如定时或者内存空间不足时,才会触发垃圾回收。

而且,垃圾回收并不是必须的(如果内存足够),垃圾回收必须满足的一个质量保证是,不能将还在使用的对象当做垃圾进行回收。

对象的比较

既然变量本身是对对象的引用,两个变量的比较,其本质是对引用对象的比较。

关于比较,在编程中有两种,一种叫同一性比较,一种叫相等性比较。

同一性比较,是判断两个变量是不是对同一个对象的两个引用、两个标签而已,同一性,显然是隐含相等性的。

相等性比较,是判断两个对象的值/内容是否相等。

a = [1, 2, 3]
b = a
c = [1, 2, 3]
# 同一性比较,通过is实现
print(a is b)
print(a is c)

# 相等性比较,通过==实现
print(a == b)
print(a == c)

执行结果:

2d06803fb6b916e44673d460ac51fe6e.jpeg

==进行的相等性判断,其实是Python中的语法糖,本质上是通过__eq__()魔法函数来实现的。所以,如果是自定义的对象,可以通过实现__eq__()函数,来实现自定义相等性的语义判断。

总结

本文将变量与对象的关系,做了进一步的解析,同时稍微提及了关于Python中的对象引用计数与垃圾回收的概念,并对对象的两种比较方式进行了简单的解释说明。

a0dd7f9e3a8f30048d1c4a00d98d1334.jpeg

在接下来的文章中,我们将进入Python新的篇章“面向对象”的介绍。

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

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

相关文章

802.11 wireshark 抓包

80211 wireshark 抓包 前言配置 monitor软件配置wireshark 操作 前言 本人习惯使用 Omnipeek 抓包分析,所以 wireshark 的实验只讲到抓包完成。 Windows 环境采用 wireshark 抓包是比较麻烦的,因为支持在 Windows 环境中支持抓包的网卡并不多&#xff0…

IP协议和路由转发

文章目录 IP协议IP报头网段划分特殊的IP私有IP和公有IP IP分片 路由 IP协议 IP协议提供了一种能力,将数据报从A主机送到B主机,TCP可以保证可靠性,所以TCP/IP协议可以将数据可靠的从A主机送到B主机。 IP报头 4位版本号(version): 指定IP协议…

【压缩泛化】对大语言模型智能涌现的理解

AGI Maximizing Compression! 1. 智能定义 一年时间,大语言模型(LLM)席卷互联网行业,包括自己在内,日常工作生活已经快离不开大模型应用了。前段时间,看到有赞干掉了30多人的UI团队,后又干掉了HRBP团队&am…

FTP、NFS、SAMBA系统服务

⼀、rsync托管xinetd 1 、为什么要进⾏服务托管 独⽴服务:独⽴启动脚本 ssh ftp nfs dns ... 依赖服务 : 没有独⽴的启动脚本 rsync telnet 依赖 xinetd 服务(独⽴服务) 2 、如何将 rsync 托管给 xinetd 服务去管理? 第⼀步&am…

无人机之航拍高级操作与技巧

一、直线飞行与矩形飞行练习:通过直线和矩形路径的练习,提升飞行路径控制能力。 二、航点命令和事件编程:学习如何设置航点命令和事件,使无人机能够自动执行复杂任务。 三、故障诊断与处理:掌握基本的故障诊断方法和…

USART串口理论知识总结

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 USART串口理论知识总结 1、通讯的串行和并行1.串口采用发送数据代码并用printf重代码 1、通讯的串行和并行 1.串口采用发送数据代码并用printf重代码 #include <stdint.h…

【C++】set的使用

&#x1f525;个人主页&#xff1a; Forcible Bug Maker &#x1f525;专栏&#xff1a; STL || C 目录 &#x1f308;前言&#x1f308;关于set&#x1f525;容量函数emptysize &#x1f525;Modifiersinserteraseclear &#x1f525;Operationsfindcountlower_bound和upper_…

Redis从入门到超神-(五)Redis实现分布式锁原理

引言 什么是分布式锁&#xff1f; 分布式锁是分布式系统中用于控制多个进程或线程对共享资源的访问的一种机制。在分布式系统中&#xff0c;由于存在多个服务实例或节点&#xff0c;它们可能会同时尝试访问或修改同一份数据或资源。如果没有适当的同步机制&#xff0c;就可能导…

谷粒商城实战笔记-46-商品服务-API-三级分类-配置网关路由与路径重写

文章目录 一&#xff0c;准备工作1&#xff0c;新增一级菜单2&#xff0c;新增二级菜单 二&#xff0c;前端树形界面开发1&#xff0c;开发分类展示组件 三&#xff0c;远程调用接口获取商品分类数据1&#xff0c;远程调用2&#xff0c;路由配置 错误记录 本节的主要内容&#…

PT2262-IR

PT2262是一款很古老的编码芯片&#xff0c;其兼容型号有&#xff1a;SC2262&#xff0c;AD2262&#xff0c;SC2260(需改变匹配电阻)等。 依据其datasheet&#xff0c;PT2262射频模式工作原理: CODE BITS A Code Bit is the basic component of the encoded waveform, and ca…

iOS实际开发中使用数据驱动页面布局

引言 在实际的APP开发中&#xff0c;我们通常会首先根据设计团队提供的视觉设计UI来构建我们的应用页面。这些设计通常是最全面和理想化的状态&#xff0c;因为设计师并不需要考虑用户的实际操作和交互。然而&#xff0c;如果我们仅仅根据这些设计进行硬编码&#xff0c;会在应…

接入百度文心一言API教程

然后&#xff0c;编辑文章。点击AI识别摘要&#xff0c;然后保存即可 COREAIPOWER设置 暂时只支持经典编辑器.古腾堡编辑器等几个版本后支持.在比期间,你可以自己写点摘要 摘要内容 AL识别摘要 清空 若有收获&#xff0c;就点个赞吧 接入文心一言 现在百度文心一言&…

php-fpm如何配置max_children参数

前言 略 php-fpm 资源耗尽 php-fpm 的子进程耗尽的时&#xff1a; 会导致 502 出现nginx 出现错误日志 2024/07/18 20:19:10 [crit] 36390#0: *1402471 connect() to unix:/tmp/php-cgi-81.sock failed (2: No such file or directory) while connecting to upstream, cli…

OpenHarmony 入门——初识JS/ArkTS 侧的“JNI” NAPI 常见的函数详解(二)

引言 前面一篇文章OpenHarmony 入门——初识JS/ArkTS 侧的“JNI” NAPI&#xff08;一&#xff09;介绍了NAPI的基础理论知识&#xff0c;今天重点介绍下NAPI中重要的函数。 一、Native 侧的NAPI的相关的C函数 以下面一段代码为例介绍下主要函数的功能和用法。 napi_value …

前端网页打开PC端本地的应用程序实现方案

最近开发有一个需求&#xff0c;网页端有个入口需要跳转三维大屏&#xff0c;而这个大屏是一个exe应用程序。产品需要点击这个入口&#xff0c;并打开这个应用程序。这个就类似于百度网盘网页跳转到PC端应用程序中。 这里我们采用添加自定义协议的方式打开该应用程序。一开始可…

Elasticsearch-RestAPI --学习笔记

RestAPI ES官方提供了各种不同语言的客户端&#xff0c;用来操作ES。这些客户端的本质就是组装DSL语句&#xff0c;通过http请求发送给ES。 官方文档地址&#xff1a; Elasticsearch Clients | Elastic 以下关于RestAPI 的说明都是基于老版本客户端 初始化RestClient 1&…

英语科技写作 希拉里·格拉斯曼-蒂(英文版)pdf下载

下载链接&#xff1a; 链接1&#xff1a;https://pan.baidu.com 链接2&#xff1a;/s/1fxRUGnlJrKEzQVF6k1GmBA 提取码&#xff1a;b69t 由于是英文版&#xff0c;可能有些看着不太方便&#xff0c;可以在网页版使用以下软件中英文对照着看&#xff0c;看着更舒服&#xff0c;…

Docker核心技术:Docker原理之Cgroups

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 Docker核心技术 系列文章&#xff1a;Docker原理之Cgroups&#xff0c;其他文章快捷链接如下&#xff1a; 应用架构演进容器技术要解决哪些问题Docker的基本使用Docker是如何实现的 Docker核心技术&#xff1a;…

扭蛋机潮玩小程序搭建,扭蛋机行业的创新

在当下潮玩市场中&#xff0c;扭蛋机具有盲盒的未知性和惊喜体验感&#xff0c;商品丰富&#xff0c;并且价格相对低廉&#xff0c;获得了极高的人气。年轻人开始对扭蛋机逐渐“上头”&#xff0c;为了扭到喜欢的商品不断地进行复购下单&#xff0c;在这场随机性的扭蛋游戏中&a…

Java语言程序设计——篇七(1)

&#x1f33f;&#x1f33f;&#x1f33f;跟随博主脚步&#xff0c;从这里开始→博主主页&#x1f33f;&#x1f33f;&#x1f33f; 继承 类的继承实战演练 方法覆盖实战演练 &#x1f351;super关键字实战演练 调用父类的构造方法 类的继承 通过类的继承方式&#xff0c;可以…