id函数 / 可变类型变量 / 不可变类型变量 / +=操作

news2024/12/26 20:50:46

前言

再说正文之前,需要大家先了解一下对象,指针和引用的含义,不懂得同学可以参考我上一篇博客“(12条消息) 引用是否有地址的讨论的_xx_xjm的博客-CSDN博客”

正文

一:python中一切皆对象

      “python中一切皆对象”这句话我相信凡是接触过python得同学应该都听过,但我想应该很少有人真正理解这句话,对此,本文在这里进行一个简单得阐述!

       在C++里面,我们说int a = 1; a就是一个对象,什么意思呢?在这里a代表了一个内存空间,我们假定这个内存空间的地址是x0001,那么a表示的是存放有1的x0001这个内存空间!所以,与其说a是一个对象,不如说是这个x0001是个对象。a和x0001的关系就是一个人和身份证上名字之间的关系,x0001就表示真实的人,a表示这个人身份证上的名字,比如“小明”。所以,我们简单理解一下,对象,就是一个真实存在的内存空间

      那么python中一切皆对象什么意思呢?还是拿上面的例子来说, int a = 1, 在这里,a代表了一个对象,一个真实的内存地址,那么1是什么呢? 1是一个立即数,是一个稍纵即逝的电流。但是在python里面对于a = 1这个式子,1其实是一个对象,也就是说,python里面,1表示的是一块存放值为1的内存空间!!!python一切皆为对象,就是说在python中,所有东西都是一个具体的内存空间!!,不管是数字,还是字符字符串,他们都是一个实际存在的内存空间

二:可变类型变量和不可变类型变量

       首先,我们先明确,python的数据类型有6中:数字number/ 字符串string / 元组 Tuple /  列表 list / 字典 dictionary / 集合 setsboolintfloatcomplex(复数)等都属于number数字类型)

      可变类型变量:字典/列表/集合

      不可变类型变量:数字/字符串/元组

关于可变类型和不可变类型变量的定义参考自:python中可变类型和不可变类型 - 百度文库 (baidu.com)

1:可变类型变量,定义如下: 

也就是说可变类型变量实际上是对象的引用,也就是对象的别名,其实指代的还是对象本身,所以对象本身当然可以对自己的数据进行变换啦。(再次强调,关于引用和指针的关系参考“(12条消息) 引用是否有地址的讨论的_xx_xjm的博客-CSDN博客“)

 2:不可变类型变量,定义如下:

 所以,不可变类型变量实际上相当于对象的指针,它存储的只是对象的地址,比如a = 1,a这个变量存储的实际上是1这个对象的地址,当然我们也可以把a当作是一个对象,在c++里面,a这种存放地址的变量叫做指针变量,实际上也是一个对象,因为它也是一个实际存在的内存空间。

三:id函数的作用(个人理解,欢迎讨论,指正)

      id函数对于可变类型变量和不可变类型变量来说,其实作用是不同的,对于可变类型变量来说,比如a = 1,a是对象1得引用,也就相当于a就是1这个对象(这句话还不理解,再看看引用得含义),id(a)取得是对象1的地址; 而对于不可变类型变量,比如a = [1,2,3],a其实是一个指针变量,也就是说a本身也是一个对象,a有自己的地址,但id(a)取得是[1,2,3]这个对象得地址。

四: +=操作得真实含义

  关于 += 的代码层面的区别在于:参考:(12条消息) python的+=和=的区别_Liquor6的博客-CSDN博客

 

   先说结论:对于不可变类型对象:i += 1和 i = i+1是一样的,都会改变 i 的地址(真实的含义是,都会改变i这个指针指向的地址),逻辑上理解为,因为不可变类型变量是指针,i指向的是一个具体的数值对象,不同的数值对象对应的内存地址不同,所以当 i 指向的数值改变了以后,i指向的地址也就变了;

     举例: 比如本来i = 1,i是一个指针变量,它指向了1这个对象的内存地址,现在 i += 1和 i = i + 1,表示的都是说 i 这个指针要指向2这个对象的地址,所以,i 指向的地址肯定会从1变成2,这就是为什么不可变对象 += 和 =+是一样的操作。

实验如下

 

 ---------------------------------------------------------------------------------------------------------------------

   同理,对于可变类型对象,比如a = [1,2,3], [1,2,3]是一个具体的对象,a是这个对象的引用,所以a += 1表示的是[ 1, 2, 3]这个对象自己加1,所以a还是这个对象的引用,但是a = a + 1则不同了,因为是引用,所以a = a + 1则表示a现在引用的应该是a + 1表示的[2,3,4]这个对象的地址,所以a = a + 1导致内存地址改变了。

实验如下:

 

结果:

 

可以看见,虽然a = [1,2,3,4],但是a这个[1,2,3,4]对象,实际上是[1,2,3]这个对象变来的,和本来的[1,2,3,4]对象是两个东西,也就是说,这里a和[1,2,3,4]对象表示的是两块内存空间,只不过两块内存空间保存的值是相同的。

再看a = a + [5]以后,这个时候a的地址是改变了的,它变成了[1,2,3,4,5]的地址,这里有一点小意思,因为我们是在a = a +[5]之前打印的[1,2,3,4,5]的id,所以,这时候[1,2,3,4,5]应该是已经被内存建立起来了,因此此时的a直接指向了[1,2,3,4,5]的内存地址,那么为什么此时[1,2,3,4,5]的地址和[1,2,3,4]的地址相同呢?因为这个时候,python其实是值记住了这个列表中1这个元素的地址,id([1,2,3,4])和id([1,2,3,4,5])返回的其实都是这个列表首元素1的地址。我们意义做如下实验,表明[1,2,3,4])和id([1,2,3,4,5]其实是一块地址空间:

 

 所以,我们来解释为什么这个时候a的地址就是[1,2,3,4,5]的地址,因为这时候内存中已经有一块连续的[1,2,3,4,5]了,并且这个值没有给任何变量(也就是没有引用),所以直接分配给了a。

那么为什么在a之后的[1,2,3,4,5]的地址又变成了最开始a=[1,2,3]的地址了呢?因为这时候a指向了新的[1,2,3,45]的地址,本来的[1,2,3]就被释放了,那么这时候的[1,2,3]就是没人管的了,那么python直接在这个基础上分发[1,2,3,4,5]的地址。由此可以看出python的内存管理机制确实很出色。更多的实验可以参照以下代码自己跑一遍:

 

补充:另外python中numpy数组是可变类型的, pytorch的张量和numpy数组共享底层内存,所以是可变类型,这就是为什么网络运行过程中,不能有原地+=操作。tensorflow的张量是不可变的。pytorch和tensorflow的张量确实是不同的。

参考:TensorFlow vs PyTorch 2: 张量(Tensor) - 简书 (jianshu.com)

五:由可变不可变类型对象引出的深浅拷贝

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

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

相关文章

【LeetCode】剑指 Offer(15)

目录 题目:剑指 Offer 32 - II. 从上到下打印二叉树 II - 力扣(Leetcode) 题目的接口: 解题思路: 代码: 过啦!!! 题目:剑指 Offer 32 - III. 从上到下打…

分子模拟—Ovito渲染案例教程

♡\heartsuit♡♠\spadesuit♠《分子模拟—Ovito渲染案例教程》♡\heartsuit♡♠\spadesuit♠: 说明: 本博文主要介绍专栏 《分子模拟—Ovito渲染案例教程》\rm 《分子模拟—Ovito渲染案例教程》《分子模拟—Ovito渲染案例教程》, 依托于实际的物理问题…

高数:数列的收敛

数列特点无限个数特定顺序数列和集合区别集合可以乱序,数列不行集合出现重复元素依然相同,数列出现新的重复元素就不相等[1,2,3,4][1,2,3,3,4]对集合来说相等&#xff0c…

【大数据实时数据同步】超级详细的生产环境OGG(GoldenGate)12.2实时异构同步Oracle数据部署方案(上)

系列文章目录 【大数据实时数据同步】超级详细的生产环境OGG(GoldenGate)12.2实时异构同步Oracle数据部署方案(上) 【大数据实时数据同步】超级详细的生产环境OGG(GoldenGate)12.2实时异构同步Oracle数据部署方案(中) 文章目录系列文章目录前言一、数据库配置信息二、下载OGG1…

LQB手打代码,DS1302基础代码01

一.描述 DS1302时钟芯片是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能。DS1302芯片包含一个用于存储实时时钟/日历的 31 字节的静态 RAM,可通过…

docker 运行花生壳实现内外网穿透

环境:centos 7 ,64位 1、创建一个指定的文件夹作为安装示例所用,该示例文件夹为“hsk-nwct”。“hsk-nwct”内创建“app”文件夹作为docker容器挂载出来的文件。 2、在“app”内下载花生壳linux安装包,下载花生壳应用:花生壳客户…

最新版本vue3+vite重构尚品汇(解决接口问题)第21-50集

第21集,第22集:照敲就行,引入概念。 第23集:防抖概念:前面所有的触发被取消,最后一次执行在规定的时间之后才会触发,只会执行一次。Lodash插件里面封装了函数的防抖和节流的业务。用到lodash确实…

SpringAOP——基础知识

AOP AOP全称是Aspect Oriented Programming 即面向切面编程,是对一类统一事务的集中处理 例如,我们的网页许多地方都需要进行登陆验证,这时就需要在很多地方添加重复的验证代码,而AOP可以集中配置需要登陆验证的地方,…

简单认识: 数据库 zhi 操作(MySQL为例)

目录 前言 一,库 二,站在巨人的肩膀上理解 库 的操作 下节预告: 前言 今天是库库森日记第n……篇之数据库篇一 库 库 库~~~~的~操~作。 如果看完这篇文章,你觉得数据库从简单的创建库,表,修改…

世界那么大,你哪都别去了,来我带你了解CSS3 (一)

文章目录‍❤️‍🔥CSS简介‍‍‍‍❤️‍🔥CSS选择器❣️选择器一❣️选择器二❣️关系选择器‍❤️‍🔥CSS属性❣️字体属性❣️背景属性❣️文本属性❣️表格属性‍❤️‍🔥CSS简介 CSS概念 CSS(Cascading Style Sh…

JWT续期问题,ChatGPT解决方案

JWT(JSON Web Token)通常是在用户登录后签发的,用于验证用户身份和授权。JWT 的有效期限(或称“过期时间”)通常是一段时间(例如1小时),过期后用户需要重新登录以获取新的JWT。然而&…

数据结构基础之链表

目录 前言 1、什么是链表 2、添加元素 3、虚拟头结点 4、查询&修改元素 5、删除元素 附:完整代码 前言 又到周末了,修整了一天,继续来写点东西吧,今天,我们来学习数据结构中的另一种基础的数据结构——链表…

jsp进阶

文章目录jsp进阶内容回顾JSP 的九大内置对象内置对象的创建九大内置对象详解四大作用域对象四大作用域范围总结EL 进阶JSTL 标准标签库JSTL 核心标签jsp进阶 内容回顾 jsp 创建 jsp 的工作原理:翻译 --> 编译 --> 运行 翻译:第一次访问 jsp 页面…

Redis简单笔记

1 为什么需要Redis 数据分冷热,将热数据存储到内存中 2 Redis应用案例 2.1 连续签到 2.1.1 String数据结构 可以存储字符串、数字、二进制数据通常和expire配合使用场景:存储计数、Session2.2 消息通知 用list作为消息队列 使用场景:消息通知。 例如当文章更新时…

机器学习模型的可解释性算法汇总!

模型可解释性汇总简 介目前很多机器学习模型可以做出非常好的预测,但是它们并不能很好地解释他们是如何进行预测的,很多数据科学家都很难知晓为什么该算法会得到这样的预测结果。这是非常致命的,因为如果我们无法知道某个算法是如何进行预测&…

巴别塔——问答平台调研

项目内容这个作业属于哪个课程2023 年北航软件工程这个作业的要求在哪里个人作业-软件案例分析我在这个课程的目标是了解软件工程的方法论、获得软件项目开发的实践经验、构建一个具有我的气息的艺术品这个作业在哪个具体方面帮助我实现目标对于“程序员是什么”这个问题有了一…

【ChatAug: Leveraging ChatGPT for Text Data Augmentation 论文精读】

ChatAug: Leveraging ChatGPT for Text Data Augmentation 论文精读InformationAbstract1 Introduction2 RELATED WORK2.1 Data Augmentation2.2 Few-shot Learning2.3 Very Large Language Models2.4 ChatGPT: Present and Future3 DATASET3.1 Symptoms Dataset3.2 PubMed20k …

Qt扫盲-CMake 使用概述

CMake 使用概述一、概述二、创建Qt CMake 项目三、简单介绍1. 引入Qt的库2.Qt CMake 引入第三方库3. Qt CMake 项目目录四、使用案例一、概述 CMake是一个简化跨不同平台开发项目的构建过程的工具。对C来说其实就是生成一个文件,文件里面描述了,怎么组织…

【MyBatis】MyBatis操作数据库

MyBatis操作数据库 文章目录MyBatis操作数据库:one:什么是MyBatis:two:创建SSM项目引入依赖配置文件设置MyBatis底层逻辑:three:实现CRUD功能查询全列查询带参数的查询新增获取自增主键删除更新:four:参数占位符:#{}和${}不支持String参数问题${}使用场景&#xff1…

javascript的ajax

学什么Ajax基础JSON跨域XHR对象Ajax进阶Ajax应用Ajax扩展Ajax基础初识 AjaxAjax的基本用法GET请求POST请求JSON初识JSONJSON的3种形式JSON的常用方法跨域初识跨域CORS跨域资源共享JSONPXHR 对象XHR的属性XHR的方法XHR的事件Ajax进阶FormData封装Ajax使用Promise改造封装好的Aja…