当前位置: 首页 > news >正文

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

前言

再说正文之前,需要大家先了解一下对象,指针和引用的含义,不懂得同学可以参考我上一篇博客“(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)

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

相关文章:

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

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

aws apigateway 使用apigateway集成lambda

参考资料 代理集成,https://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html非代理集成,https://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/getting-started-…...

Linux SPI 驱动实验

目录 一、Linux 下 SPI 驱动框架简介 1、SPI 主机驱动 2、SPI 设备驱动 SPI 设备数据收发处理流程 3、SPI 设备和驱动匹配过程 二、添加SPI 设备信息 1、添加 ICM20608 所使用的 IO 2、 在 ecspi3 节点追加 icm20608 子节点 三、编写 ICM20608 驱动 1、修改makefile​…...

[1.4]计算机系统概述——操作系统的体系结构

第一章 计算机系统概述 操作系统的体系结构 大内核/单内核/宏内核微内核 通过之前的学习,我们知道计算机系统的层次结构是这样的。 但是操作系统的内部其实还可以再进一步地划分。 一部分是内核的功能,一部分是非内核的功能。 操作系统最核心的功能&…...

FPGA的GigE Vision IP相机图像采集方案设计,转换为千兆UDP,支持10G MAC

1 概述 GigE Vision是一个比较复杂的协议,要在FPGA中完全实现具有较大的难度。如果FPGA作为接收端希望实现GigE Vision相机的配置和图像采集功能,则只需要实现其中小部分功能即可。本文对原有GigE Vision协议的结构进行了裁剪,仅保留设备搜索…...

大数据相关面试题

linux 常见linux高级命令? top、iotopnetstatdf -hjmap -heaptarrpmps -efshell 用过的shell工具? awk Awk 命令详解 - 简书 awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来…...

AI绘画第二步,抄作业复现超赞的效果!

上一篇,讲了如何安装AI绘画软件,但是装完后发现生成效果很渣!而网上那些效果都很赞。真的是理想很丰满,现实很骨感。今天就是来聊聊如何抄作业,最大程度的还原那些超赞的效果。换一种说法就是,教大家如何使…...

Python的并发编程

我们将一个正在运行的程序称为进程。每个进程都有它自己的系统状态,包含内存状态、打开文件列表、追踪指令执行情况的程序指针以及一个保存局部变量的调用栈。通常情况下,一个进程依照一个单序列控制流顺序执行,这个控制流被称为该进程的主线…...

【Linux】基本系统维护命令

😊😊作者简介😊😊 : 大家好,我是南瓜籽,一个在校大二学生,我将会持续分享C/C相关知识。 🎉🎉个人主页🎉🎉 : 南瓜籽的主页…...

高数:数列的收敛

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

不平凡的一天——

作者:指针不指南吗 专栏:个人日常记录 🐾或许会很慢,但是不可以停下来🐾 文章目录1.自我介绍2.上学期3.不凡的一天4.新学期写个博客,简单记录一下,新学期加油!!&#xff…...

【Java基础】Map遍历的5种方式

目录 创建一个集合 方式一:Iterator 迭代器遍历 map.entrySet().iterator(); map.keySet().iterator(); 方式二:For Each方式遍历 map.forEach(BiConsumer action) 方式三:获取Collection集合 map.values().forEach() 方式四&#x…...

第十四届蓝桥杯三月真题刷题训练——第 2 天

目录 题目1:奇数倍数 代码: 题目2:求值 代码: 题目3:求和 代码: 题目4:数位排序 代码: 题目1:奇数倍数 题目描述 本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即…...

自然语言处理历史最全预训练模型(部署)汇集分享

什么是预训练模型?预练模型是其他人为解决类似问题而创建的且已经训练好的模型。代替从头开始建立模型来解决类似的问题,我们可以使用在其他问题上训练过的模型作为起点。预训练的模型在相似的应用程序中可能不是100%准确的。本文整理了自然语…...

csdn写文章自定义表格怎么做

前言 CSDN写文章时,经常会用到表格,不同于Word文档中直接插入表格(自定义几行几列),使用CSDN自带的md文本编辑器时,很难快速插入想要的表格样式,追究原因,也是因为md的语法问题&…...

Pytorch处理数据与训练网络问题汇总(协同训练)

基础语法 模型训练 【Swin-Unet】官方代码预训练权重加载函数load_from() 实际上由于SwinUnet是一个encoder-decoder对称的结构,因此加载权重时,作者并没有像通常那样仅仅加载encoder部分而不加载decoder部分,而是同时将encoder的权重对称地…...

机器学习:基于神经网络对用户评论情感分析预测

机器学习:基于神经网络对用户评论情感分析预测 作者:AOAIYI 作者简介:Python领域新星作者、多项比赛获奖者:AOAIYI首页 😊😊😊如果觉得文章不错或能帮助到你学习,可以点赞&#x1f4…...

Vue3之组件间传值避坑指南

组件间传值的两个坑 我们都知道父组件可以把值传递到自组件中,但是有时候子组件需要修改这个父组件传递过来的这个值,我们可以想象下能修改成功吗?这是坑之一。我们在组件间传值的时候,都是一个属性名对应一个值,接收…...

02-问题思考维度:抓住核心用户、场景化分析、需求收集与辨别、用户故事

文章目录2.1 抓住核心用户2.1.1 为什么要抓住核心用户2.1.2 核心用户的特征根据不同维度,描述核心用户2.1.3 如何抓住核心用户2.2 场景化分析2.2.1 场景五要素2.2.2 场景化分析方法2.2.3 场景化分析方法的应用2.3 需求收集与辨别2.3.1 需求的定义及层次2.3.2 需求收…...

C 语言编程 — GCC Attribute 语法扩展

目录 文章目录目录Attribute 属性扩展机制__attribute__((packed))__attribute__((aligned(n)))__attribute__((noreturn))__attribute__((unused))Attribute 属性扩展机制 GCC 的特点之一就是 Attribute 语法扩展机制,通过使用 __attribute__ 关键字可以设置以下对…...

如何高效使用Zettlr:开源写作工具的实用配置与技巧指南

如何高效使用Zettlr:开源写作工具的实用配置与技巧指南 【免费下载链接】Zettlr Your One-Stop Publication Workbench 项目地址: https://gitcode.com/GitHub_Trending/ze/Zettlr 还在为学术写作和知识管理寻找一个功能全面、界面简洁的跨平台工具吗&#x…...

别再乱装CUDA了!保姆级教程:从显卡驱动到PyTorch 2.x,一次搞定Windows深度学习环境

深度学习环境配置避坑指南:从显卡驱动到PyTorch 2.x全流程解析 刚接触深度学习的开发者,往往在环境配置阶段就遭遇重重阻碍。显卡驱动与CUDA版本不匹配、cuDNN安装失败、PyTorch下载缓慢等问题,让许多初学者在起步阶段就耗费大量时间。本文将…...

LangChain实战避坑:我的RAG项目为什么召回结果不准?从向量化到混合检索的调优全记录

LangChain实战调优:从召回失败到精准检索的完整解决方案 当你的RAG系统在回答"夏天旅行推荐"时,返回了撒哈拉沙漠海滩和新疆火山口这类荒谬结果,问题可能出在文本分割、嵌入模型或混合检索策略上。本文将分享一套经过实战验证的调优…...

新手入门指南:在快马平台用AI生成代码理解云桌面基础概念

今天想和大家分享一个特别适合新手理解云桌面基础概念的实践方法。作为一个刚接触云计算的小白,我最初对"一台主机创建多个云桌面"这个概念也是一头雾水,直到在InsCode(快马)平台上尝试用AI生成代码来模拟这个过程,才真正搞明白其中…...

为什么LivePortrait能吊打Diffusion模型?揭秘快手69M训练数据背后的技术取舍

LivePortrait为何能突破扩散模型瓶颈?解析69M训练数据驱动的工业级优化策略 当开源社区还在为扩散模型的生成质量惊叹时,快手LivePortrait团队已经用12.8ms/帧的推理速度和6.5K GitHub星标证明:在工业级人像动画领域,隐式关键点框…...

Ascend CANN平台避坑指南:从算子开发到模型部署的5个关键陷阱

Ascend CANN平台避坑指南:从算子开发到模型部署的5个关键陷阱 在AI加速器领域,昇腾NPU凭借其独特的达芬奇架构和CANN软件栈,正在成为越来越多企业级AI部署的首选方案。然而在实际工程落地过程中,从算子开发到模型部署的完整链路里…...

别再死记公式了!用Multisim仿真软件,10分钟搞懂555定时器的三种工作模式

用Multisim玩转555定时器:可视化学习三种工作模式的终极指南 记得第一次接触555定时器时,我被那些复杂的公式和抽象的工作原理搞得晕头转向。直到一位资深工程师告诉我:"别急着背公式,先看看它怎么工作。"这句话彻底改变…...

Linux 中的硬链接和软连接是什么,二者有什么区别?

在 Linux 文件系统中,**硬链接(Hard Link)和软链接(Soft Link,又称符号链接 Symbolic Link)**是两种不同的文件引用方式。它们都允许用户通过不同的路径访问同一个文件内容,但它们的实现机制、限…...

LFM2.5-1.2B-Thinking-GGUF部署教程:Ubuntu/CentOS/Debian三平台通用安装步骤

LFM2.5-1.2B-Thinking-GGUF部署教程:Ubuntu/CentOS/Debian三平台通用安装步骤 1. 平台简介 LFM2.5-1.2B-Thinking-GGUF是Liquid AI推出的轻量级文本生成模型,特别适合在资源有限的环境中快速部署。该镜像内置了GGUF模型文件和llama.cpp运行时&#xff…...

Qwen3.5-2B入门指南:如何将本地7860服务映射为公网可访问API接口

Qwen3.5-2B入门指南:如何将本地7860服务映射为公网可访问API接口 1. 引言 Qwen3.5-2B是阿里云推出的轻量化多模态基础模型,属于Qwen3.5系列的小参数版本(20亿参数)。这个模型主打低功耗、低门槛部署,特别适合在端侧和…...