Python-VBA函数之旅-id函数

目录

一、id函数的常见应用场景:

二、id函数使用注意事项:

1、id函数:

1-1、Python:

1-2、VBA:

2、推荐阅读:

个人主页:神奇夜光杯-CSDN博客 



一、id函数的常见应用场景:

        id函数在Python中有一些实际应用场景,尽管它在日常编程中并不常用,常见的应用场景有:

1、调试和内存管理:在开发过程中,特别是在处理复杂的数据结构或进行性能优化时,id()函数可以用来检查对象是否在内存中被正确地创建和销毁,通过比较对象的id,可以追踪对象的生命周期,以及检测是否发生了意外的对象复制或重复创建。

2、检查对象是否相同:虽然通常我们使用`==`操作符来比较两个对象的值是否相等,但id()函数可以用来检查两个引用是否指向内存中的同一个对象,这在某些情况下可能是有用的,特别是当你需要确保两个引用不指向同一个可变对象,以避免意外的共享状态。

3、单例模式实现:在单例模式中,确保一个类只有一个实例,并提供一个全局访问点,在实现单例时,id()函数可以用来检查是否已经创建了实例,从而避免重复创建。

4、性能分析和优化:id()函数可以帮助你了解对象的创建和销毁情况,这对于性能分析和优化可能是有用的。例如,如果你发现某个函数在每次调用时都创建了大量的临时对象,这可能会导致不必要的内存分配和垃圾回收开销,通过检查这些对象的id,你可以确定它们是否在每次调用时都被重新创建。

5、缓存和重用对象:在某些情况下,你可能希望重用已经创建过的对象,而不是每次都创建新的对象,通过存储对象的id,你可以检查是否已经创建了具有相同属性或状态的对象,并重用它们而不是创建新的。

        注意,id()函数返回的是对象的内存地址,这取决于Python解释器的实现和当前的内存状态。因此,它不应该被用于一般的对象比较或逻辑判断,在大多数情况下,应该使用`==`操作符来比较对象的值,使用`is`操作符来比较对象的身份(即它们是否指向同一个对象)。

二、id函数使用注意事项:

        在Python中使用id()函数时,需要注意以下几点:

1、不要依赖特定的id值:id()函数返回的是对象的“标识”或内存地址,这个值依赖于Python解释器的实现和当前内存状态。因此,不要编写依赖于特定id值的代码,因为不同运行时刻或不同解释器中的相同对象可能会有不同的id。

2、不要用于比较对象的相等性:即使两个对象具有相同的值,它们的id也可能不同,因为它们是内存中的不同实例。相反,即使两个对象的id相同,也不意味着它们的值一定相等(尽管在对象的生命周期内,id相同的对象必然是同一个对象),因此,不要使用id()函数来比较对象的相等性,而应该使用`==`操作符。

3、不要用于跨不同解释器或会话的对象比较:由于id()返回的是内存地址,这个地址只在当前的Python解释器实例和会话中有效,如果你试图在不同的解释器实例或会话之间比较对象的id,那么这将没有意义,因为每个解释器实例都有自己独立的内存空间。

4、不要用于跨不同程序执行的对象比较:即使在同一解释器会话中,如果你在不同的程序执行(例如,通过多次启动Python脚本)中创建相同的对象,它们的id也可能不同,因为每次执行时内存布局都可能发生变化。

5、不要用于对象的持久化存储:id()函数返回的id是特定于当前内存布局的,因此不应该用于对象的持久化存储或跨不同执行环境的比较。如果你需要跨不同执行环境或持久化存储中唯一标识对象,应该使用其他机制,如UUID或数据库主键。

6、注意对象回收和内存重用:当对象被垃圾回收后,其id可能会被重新分配给新创建的对象,因此,不要假设已删除对象的id永远不会再次被使用。

7、谨慎用于性能优化:虽然id()函数有时可以用于性能分析和内存优化,但通常更好的做法是使用Python内置的分析工具(如`memory_profiler`)或专门的性能分析工具。直接依赖id()函数进行性能优化可能会使代码难以理解和维护。

        总之,id()函数主要用于调试和内部检查,而不是用于常规的编程逻辑或对象比较,在编写代码时,应该尽量避免依赖对象的id,而是使用更稳定、更可预测的比较和标识机制。

1、id函数:
1-1、Python:
# 1.函数:id
# 2.功能:用于获取对象的内存地址
# 3.语法:id(object)
# 4.参数:object,对象
# 5.返回值:一个整数,返回对象的内存地址
# 6.说明:
# 6-1、返回一个整数,在此对象的生命周期中保证是唯一且恒定的
# 6-2、两个生命期不重叠的对象可能具有相同的id()值
# 7.示例:
# 应用1:调试和内存管理
# 理解对象身份
# 创建两个相同的整数对象
a = 10
b = 10
# 打印它们的id
print(f"ID of a: {id(a)}")
print(f"ID of b: {id(b)}")
# 由于Python对小的整数进行了缓存,所以a和b可能指向同一个对象
# 因此,它们的id可能相同
# ID of a: 140715802354760
# ID of b: 140715802354760

# 理解对象赋值
# 创建一个列表对象
list1 = [3, 5, 6]
print(f"ID of list1: {id(list1)}")
# 将list1赋值给list2
list2 = list1
print(f"ID of list2: {id(list2)}")
# list1和list2指向同一个对象,所以它们的id相同
# ID of list1: 2581367673280
# ID of list2: 2581367673280

# 理解对象复制
# 创建一个列表对象
list1 = [3, 5, 6]
print(f"ID of list1: {id(list1)}")
# 使用切片操作复制list1
list2 = list1[:]
print(f"ID of list2: {id(list2)}")
# list2是list1的一个新副本,所以它们有不同的id
# ID of list1: 2333963122432
# ID of list2: 2333963122560

# 理解对象在内存中的变化
# 创建一个列表对象
list1 = [3, 5, 6]
print(f"ID of list1 before modification: {id(list1)}")
# 修改列表
list1.append(8)
print(f"ID of list1 after modification: {id(list1)}")
# 修改列表不会改变它的id,因为列表对象在内存中的位置没有改变
# 只是列表的内容发生了变化
# ID of list1 before modification: 2302696935872
# ID of list1 after modification: 2302696935872

# 应用2:检查对象是否相同
# 检查两个整数是否指向相同的对象
a = 123
b = 123
# 使用id()函数检查它们的身份是否相同
if id(a) == id(b):
    print("a 和 b 指向相同的对象")
else:
    print("a 和 b 指向不同的对象")
# 对于小的整数,Python通常会缓存它们,所以a和b可能指向相同的对象
# 但是,这并非总是如此,所以这种方法并不完全可靠来检查整数值是否相等
# a 和 b 指向相同的对象

# 检查两个列表是否指向相同的对象
list1 = [1, 2, 3]
list2 = list1  # list2是list1的引用,它们指向同一个对象
list3 = [1, 2, 3]  # list3是一个新的列表对象,与list1内容相同但身份不同
# 使用id()函数检查它们的身份
if id(list1) == id(list2):
    print("list1 和 list2 指向相同的对象")
else:
    print("list1 和 list2 指向不同的对象")
if id(list1) == id(list3):
    print("list1 和 list3 指向相同的对象")
else:
    print("list1 和 list3 指向不同的对象")
# 在这个例子中,list1和list2指向同一个对象,而list1和list3指向不同的对象,尽管它们的内容相同
# list1 和 list2 指向相同的对象
# list1 和 list3 指向不同的对象

# 使用is运算符检查对象身份
if list1 is list2:
    print("list1 is list2(它们指向相同的对象)")
else:
    print("list1 is not list2")
if list1 is list3:
    print("list1 is list3(它们指向相同的对象)")
else:
    print("list1 is not list3")
    # is运算符是检查对象身份更直接、更常见的方法
# list1 is list2(它们指向相同的对象)
# list1 is not list3

# 应用3:单例模式实现
class Singleton:
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance
    def __init__(self, value):
        self.value = value
# 创建第一个实例
singleton1 = Singleton(42)
print(f"ID of singleton1: {id(singleton1)}")
# 尝试创建第二个实例
singleton2 = Singleton(24)
print(f"ID of singleton2: {id(singleton2)}")
# 检查两个实例是否相同
if singleton1 is singleton2:
    print("singleton1 and singleton2 are the same instance")
else:
    print("singleton1 and singleton2 are different instances")
# 使用id()函数进一步验证
if id(singleton1) == id(singleton2):
    print("ID of singleton1 and singleton2 are the same")
else:
    print("ID of singleton1 and singleton2 are different")
# ID of singleton1: 2438427103696
# ID of singleton2: 2438427103696
# singleton1 and singleton2 are the same instance
# ID of singleton1 and singleton2 are the same

# 应用4:缓存和重用对象
class ObjectCache:
    def __init__(self):
        self.cache = {}
    def get_or_create(self, key, creator_function, *args, **kwargs):
        """
        根据key获取对象,如果不存在则使用creator_function创建并缓存。
        """
        if key not in self.cache:
            # 调用creator_function创建新对象,并传入额外的参数
            new_object = creator_function(*args, **kwargs)
            # 将新对象添加到缓存中
            self.cache[key] = new_object
            # 返回缓存中的对象
        return self.cache[key]
# 示例:创建一个缓存对象
cache = ObjectCache()
# 假设我们有一个创建对象的函数
def create_expensive_object(id):
    print(f"Creating object with ID: {id}")
    # 这里模拟创建一个昂贵的对象(比如从数据库加载或执行复杂计算)
    return f"Object {id}"
# 尝试获取一个ID为1的对象
obj1 = cache.get_or_create('1', create_expensive_object, '1')
print(f"Object with ID 1: {obj1}")
# 再次尝试获取ID为1的对象,这次应该直接从缓存中获取
obj2 = cache.get_or_create('1', create_expensive_object, '1')
print(f"Object with ID 1 (cached): {obj2}")
# 检查两个对象是否相同(实际上是缓存中的同一个对象)
print(f"obj1 is obj2: {obj1 is obj2}")
# 尝试获取一个ID为2的新对象
obj3 = cache.get_or_create('2', create_expensive_object, '2')
print(f"Object with ID 2: {obj3}")
# Creating object with ID: 1
# Object with ID 1: Object 1
# Object with ID 1 (cached): Object 1
# obj1 is obj2: True
# Creating object with ID: 2
# Object with ID 2: Object 2
1-2、VBA:
略,待后补。
2、推荐阅读:

1、Python-VBA函数之旅-hex()函数

Python算法之旅:Algorithm

Python函数之旅:Functions 

个人主页:神奇夜光杯-CSDN博客 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Linux开发实用篇】备份与恢复

备份 实体机无法做快照,我们可以使用备份和恢复技术 第一种方式 把需要的文件(或者分区)用TAR打包就好,下次恢复的时候进行解压 第二种方式 使用dump 和 restore 指令: 首先安装这两个指令 yum -y install dump, …

2024平替电容笔买哪个品牌好?iPad电容笔全能榜单热门款TOP5分享!

2024年,随着科技的不断发展和消费者对生活品质的追求,电容笔作为一种创新的无纸化工具,逐渐走进人们的生活和工作中。然而,在电容笔市场的繁荣背后,也隐藏着品质良莠不齐的现象。众多品牌为了追求利润,推出…

Ubuntu 安装 Harbor

一、安装 docker 原文参考传送门 1st 卸载系统自带的 docker 应用 for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done 2nd 设置Docker 的apt源 # Add Dockers official GPG key: sudo…

2024/4/23 C++day1

有以下定义,说明哪些量可以改变哪些不可以改变? const char *p; 指针可以改变 值不可以改变 const (char *) p; 语法错误 char *const p; 指针不可以改变 值可以改变 const char* const p; 指针和值…

做抖音小店正确起店的方式,新店铺想快速爆单,步骤就这几个

大家好,我是电商笨笨熊 开通了抖音小店,但是店铺一直没有流量; 很多新手玩家进入抖店后都会遇到这样那样的问题,烦恼的事情一大堆; 没关系,今天我们就来聊聊新店铺该怎么快速起店,新手如何做…

使用CSS3 + Vue3 + js-tool-big-box工具,实现炫酷五一倒计时动效

时间过得真是飞速,很快又要到一年一度的五一劳动节啦,今年五天假,做好准备了吗?今天我们用CSS3 Vue3 一个前端工具库 js-tool-big-box来实现一个炫酷的五一倒计时动效吧。 目录 1 先制作一个CSS3样式 2 Vue3功能提前准备 3…

莫名锁表? --- mysql的事务隔离级别

前言 系统响应超时 系统访问数据库特别慢 莫名提示锁等待超时 数据库锁表 事务长时间等锁,直到超时 以上问题都可能是事务锁表导致的 问题 今天测试反馈系统批量处理莫名提示锁等待超时,再次操作查看数据库事务确实存在等锁情况,甚至死锁。…

模版初阶【C++】

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ 🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿&#x1…

NLP自然语言处理_序章

开一个新篇章,立一个flag,用一段时间来学习一下NLP,涨涨见识。 准备以B站 机器学习算法到transformer神经网络模型应用视频作为入门,此分类专门用于记录学习过程中的知识点以备自用。 一、何为NLP自然语言处理? NLP…

云原生的基石:containerd引领未来容器发展趋势

文章目录 一、Containerd简介:容器技术的心脏二、Containerd核心原理解析三、Containerd与Docker的关系四、Containerd在云原生应用部署中的作用五、Containerd的扩展性和插件机制六、Containerd的安全特性七、Containerd的性能优化八、Containerd的社区和生态系统九…

文本向量化模型新突破——acge_text_embedding勇夺C-MTEB榜首

在人工智能的浪潮中,以GPT4、Claude3、Llama 3等大型语言模型(LLM)无疑是最引人注目的潮头。这些模型通过在海量数据上的预训练,学习到了丰富的语言知识和模式,展现了出惊人的能力。在支撑这些大型语言模型应用落地方面…

RTSP/Onvif视频监控平台EasyNVR如何提高匿名用户的用户名和密码安全性?

EasyNVR安防视频云平台是旭帆科技TSINGSEE青犀旗下支持RTSP/Onvif协议接入的安防监控流媒体视频云平台。平台具备视频实时监控直播、云端录像、云存储、录像检索与回看、告警等视频能力,能对接入的视频流进行处理与多端分发,包括RTSP、RTMP、HTTP-FLV、W…

tcp inflight 守恒算法背后的哲学

tcp inflight 守恒拥塞控制的正确性 很久以前我开始纠结 tcp 锯齿,很多年后我知道这叫 capacity-seeking,甚至说 tcp 属于 capacity-seeking protocol 的原因就是它早已深入人心的 aimd 行为,而该行为生成了 tcp 锯齿。 在消除锯齿&#xf…

Python-VBA函数之旅-input函数

目录 一、input函数的常见应用场景: 二、input函数使用注意事项: 三、如何用好input函数? 1、input函数: 1-1、Python: 1-2、VBA: 2、推荐阅读: 个人主页:神奇夜光杯-CSDN博…

hcia datacom课程学习(7):直连路由、静态路由

直连路由路由器接口上的网络(接口配置了IP地址并且开启)静态路由管理员手工添加的网络动态路由路由器之间动态学习形成的网络 1.直连路由 每当给路由器的一个接口配置了ip,路由表中就会产生对应的直连路由 配置路由接口ip的命令&#xff1…

web测试基础知识

目录 web系统的基础 web概念(worldwideweb) 网络结构 发展 架构 B/S C/S P2P 工作原理 静态页面 动态页面 web客户端技术 浏览器的核心--渲染引擎 web服务器端技术 web服务器 应用服务器 集群环境 数据库 案例-URL 协议类型 主机名 端口 IP地址 分类 …

【国产替代】航空电子通信总线航空电子通信总线产品为MIL-STD-1553和ARINC 429等协议提供原生支持

航空电子通信总线 航空电子通信总线产品为MIL-STD-1553和ARINC 429等协议提供原生支持。这些产品用于进行航空电子应用所需的开发、生产和系统测试。 PXIe,2通道PXI ARINC-664接口模块 AIM ARINC-664具有板载处理器,可自动处理所有与协议相关的活动&…

Java进阶-日志框架

概述 小结 体系 Logback概述 Logback快速入门 1.下载 一般情况,Logback日志框架只需要下载slf4j-api、logback-core、logback-classic这三个jar包即可。 slf4j-api-1.7.26.jar官网下载链接: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7…

docker部署通义千问-7B-Chat的openai-api环境

服务器环境: 显卡驱动:Driver Version: 530.30.02 CUDA版本:CUDA Version: 12.1 显卡:NVIDIA GeForce RTX 3090共4张 注意:最好把显卡驱动升级到530,CUDA版本之前使用11.7有问题。 一、下载模型文件 …

炉管设备的内部构造详解

知识星球(星球名:芯片制造与封测社区)里的学员问:炉管设备(立式)的内部构造是怎样的? 如上图,是一个典型的: 上半部: Heating Element(加热线圈…
最新文章