Python-3.12.0文档解读-内置函数id()详细说明+记忆策略+常用场景+巧妙用法+综合技巧


一个认为一切根源都是“自己不够强”的INTJ

个人主页:用哲学编程-CSDN博客
专栏:每日一题——举一反三
Python编程学习
Python内置函数

Python-3.12.0文档解读

目录

详细说明

概述

参数

返回值

特性

实现细节(CPython)

安全性

示例

注意事项

相关函数

参考文献

记忆策略

常用场景

场景 1:比较两个对象是否是同一个对象

场景 2:跟踪对象的生命周期

场景 3:检测对象的共享与复制

场景 4:检测变量是否指向None

巧妙用法

巧妙使用 1:检测对象是否被回收

巧妙使用 2:基于对象ID的唯一性生成哈希值

巧妙使用 3:对象池管理

巧妙使用 4:缓存机制

综合技巧

巧妙用法 1:与 weakref 模块结合,用于对象生命周期管理

巧妙用法 2:与 inspect 模块结合,用于调试和跟踪对象

巧妙用法 3:与 gc 模块结合,用于垃圾回收调试

巧妙用法 4:与自定义装饰器结合,实现缓存优化

巧妙用法 5:与 __slots__ 结合,优化内存使用


详细说明

概述

id(object) 函数用于返回对象的“标识值”。该标识值是一个整数,在对象的生命周期中保证唯一且恒定。

参数
  • object:任何Python对象。
返回值

id(object) 返回一个整数,表示对象的唯一标识值。

特性
  • 唯一性:在对象的生命周期中,标识值是唯一的。
  • 恒定性:在对象的生命周期中,标识值是恒定不变的。
  • 范围:两个生命周期不重叠的对象可能具有相同的id值。
实现细节(CPython)

在CPython实现中,id() 返回对象在内存中的地址。因此,标识值实际上是对象指针的内存地址。

安全性

调用id()函数时会引发一个审计事件 builtins.id,伴随的参数是返回的标识值。这意味着在一些受限或敏感的环境中(例如某些安全模式或沙盒环境),调用此函数可能有额外的安全审查或限制。

示例

以下是一些使用 id() 函数的示例:

a = [1, 2, 3]
b = a
c = [1, 2, 3]print(id(a))  # 输出类似于 140437284863232
print(id(b))  # 输出与 id(a) 相同,因为 b 是对 a 的引用
print(id(c))  # 输出不同的值,因为 c 是一个新的列表对象
注意事项
  • 使用id()时要意识到,虽然返回值在对象生命周期内是唯一的,但当对象被销毁后,内存地址可能会被新的对象重用,因此在不同的时间点,相同的id值并不保证代表同一个对象。
  • 在调试或需要精确追踪对象引用的场景中,id()函数非常有用。
相关函数
  • hash(object):返回对象的哈希值。
  • is 运算符:比较两个对象的标识值是否相同。
参考文献
  • Python 官方文档 - id() 函数(https://docs.python.org/3/library/functions.html#id)
  • PEP 578 -- Python Runtime Audit Hooks(https://www.python.org/dev/peps/pep-0578/)

通过理解 id(object) 函数,可以更好地掌握Python中对象的内存管理和引用机制。


记忆策略

功能联想法:记住 id 函数是返回对象的唯一标识值时,可以联想到它的功能是与“标识”(identifier)相关的。在英语中,“标识”一词为 identifier,而 id 是它的缩写。


常用场景

以下是 id(object) 函数在实际编程中几个最有用的使用场景,并且每行代码都有详细的注释。

场景 1:比较两个对象是否是同一个对象

在Python中,使用 id() 可以判断两个对象是否实际上是同一个对象。这比使用 == 更深入,因为 == 比较的是对象的值,而 id() 比较的是对象的身份。

a = [1, 2, 3]  # 创建一个列表对象
b = a  # 将 b 引用到 a,实际上 b 和 a 是同一个对象
c = [1, 2, 3]  # 创建另一个列表对象,内容相同但对象不同# 比较对象的标识值
print(id(a) == id(b))  # 输出 True,a 和 b 是同一个对象
print(id(a) == id(c))  # 输出 False,a 和 c 是不同的对象# 使用 `is` 运算符进行同样的比较
print(a is b)  # 输出 True,a 和 b 是同一个对象
print(a is c)  # 输出 False,a 和 c 是不同的对象
场景 2:跟踪对象的生命周期

通过 id() 函数可以跟踪对象在程序运行过程中的生命周期,特别是在调试时可以确认对象是否被创建或销毁。

class MyClass:passdef create_and_print_id():obj = MyClass()  # 创建一个对象obj_id = id(obj)  # 获取对象的标识值print(f'Object ID inside function: {obj_id}')  # 打印对象的标识值return obj_idobj_id_outside = create_and_print_id()
print(f'Object ID outside function: {obj_id_outside}')  # 再次打印对象的标识值# 尝试再次创建对象并比较标识值
new_obj = MyClass()
new_obj_id = id(new_obj)
print(f'New Object ID: {new_obj_id}')  # 打印新创建对象的标识值# 检查是否与之前的对象标识值相同
print(obj_id_outside == new_obj_id)  # 输出 False,如果是不同对象
场景 3:检测对象的共享与复制

在某些情况下,了解对象是共享的(引用相同的对象)还是被复制的(创建了新对象),对调试和优化代码很重要。

import copyoriginal_list = [1, 2, 3]  # 创建一个原始列表对象
shared_list = original_list  # 共享原始列表
copied_list = copy.deepcopy(original_list)  # 深复制原始列表print(id(original_list))  # 输出原始列表的标识值
print(id(shared_list))  # 输出与原始列表相同的标识值,因为是同一个对象
print(id(copied_list))  # 输出不同的标识值,因为是深复制的新对象# 使用 `is` 运算符进行同样的检查
print(original_list is shared_list)  # 输出 True,两个引用指向同一个对象
print(original_list is copied_list)  # 输出 False,两个引用指向不同的对象
场景 4:检测变量是否指向None

当需要确认一个变量是否指向 None 时,可以通过 id() 来确认。

none_var = None  # 创建一个 `None` 类型的变量
some_var = 42  # 创建一个非 None 的变量none_id = id(None)  # 获取 `None` 的标识值# 检查变量的标识值是否与 `None` 的标识值相同
print(id(none_var) == none_id)  # 输出 True,因为 none_var 是 None
print(id(some_var) == none_id)  # 输出 False,因为 some_var 不是 None

以上是几个常见且实用的 id(object) 函数的使用场景,每个例子都包括详细的注释,帮助理解其用法和作用。


巧妙用法

id(object) 函数虽然看似简单,但在一些特定场景下可以通过巧妙的应用来解决问题或优化代码。以下是一些一般人可能想不到的使用技巧:

巧妙使用 1:检测对象是否被回收

在某些情况下,你可能需要确认一个对象是否已经被垃圾回收器回收。通过 id() 和弱引用(weakref 模块),你可以实现这一目的。

import weakrefclass MyClass:pass# 创建对象并获取其标识值
obj = MyClass()
obj_id = id(obj)# 创建弱引用
weak_ref = weakref.ref(obj)# 删除原始引用
del obj# 检查对象是否已经被回收
if weak_ref() is None:print(f'Object with id {obj_id} has been garbage collected.')
else:print(f'Object with id {obj_id} is still alive.')

巧妙使用 2:基于对象ID的唯一性生成哈希值

在一些应用场景中,可能需要为对象生成唯一的哈希值。虽然Python的hash()函数已经提供了对象的哈希值,但在某些情况下,基于对象ID生成哈希值可能更实用。

class UniqueHasher:def __init__(self, obj):self.obj = objself.obj_id = id(obj)def __hash__(self):return self.obj_idmy_obj = UniqueHasher([1, 2, 3])
print(hash(my_obj))  # 输出对象的唯一哈希值,基于其 id

巧妙使用 3:对象池管理

在需要管理大量对象实例的场景中,可以使用 id() 来跟踪和管理对象池,确保对象的唯一性和复用性。

class ObjectPool:def __init__(self):self._pool = {}def get(self, obj_class):obj = obj_class()obj_id = id(obj)if obj_id not in self._pool:self._pool[obj_id] = objreturn self._pool[obj_id]class MyClass:passpool = ObjectPool()obj1 = pool.get(MyClass)
obj2 = pool.get(MyClass)print(id(obj1))  # 输出 obj1 的标识值
print(id(obj2))  # 输出 obj2 的标识值,应该与 obj1 一样# 因为 obj1 和 obj2 实际上是同一个对象
print(obj1 is obj2)  # 输出 True

巧妙使用 4:缓存机制

通过 id() 可以实现基于对象唯一标识的缓存机制,特别适用于需要频繁访问相同对象的场景。

class CachedObject:_cache = {}def __new__(cls, value):obj_id = id(value)if obj_id in cls._cache:return cls._cache[obj_id]new_obj = super(CachedObject, cls).__new__(cls)cls._cache[obj_id] = new_objreturn new_objdef __init__(self, value):self.value = value# 初始化并缓存对象
obj1 = CachedObject([1, 2, 3])
obj2 = CachedObject([1, 2, 3])print(id(obj1))  # 输出 obj1 的标识值
print(id(obj2))  # 输出 obj2 的标识值,应该与 obj1 一样# 因为 obj1 和 obj2 实际上是同一个对象
print(obj1 is obj2)  # 输出 True

通过这些巧妙的使用技巧,id(object) 函数可以在对象管理、内存优化、缓存机制等多个方面发挥意想不到的作用。


综合技巧

id(object) 函数可以与其他函数或方法组合使用,以解决一些复杂的问题或实现巧妙的功能。以下是一些示例,这些示例展示了如何将 id() 与其他函数或方法结合使用,以实现独特且实用的效果。

巧妙用法 1:与 weakref 模块结合,用于对象生命周期管理

通过 id() 和 weakref 模块的结合,可以监控对象的生命周期,实现对象缓存或对象池的自动清理。

import weakrefclass MyClass:passclass ObjectManager:def __init__(self):self._objects = weakref.WeakValueDictionary()def get_object(self):obj = MyClass()obj_id = id(obj)self._objects[obj_id] = objreturn objdef is_alive(self, obj):return id(obj) in self._objectsmanager = ObjectManager()
obj1 = manager.get_object()
obj_id1 = id(obj1)print(manager.is_alive(obj1))  # 输出 True# 删除引用后检查对象是否仍然存在
del obj1
print(manager.is_alive(obj_id1))  # 输出 False

巧妙用法 2:与 inspect 模块结合,用于调试和跟踪对象

通过 id() 和 inspect 模块,可以在调试时更深入地了解对象的状态和属性,帮助识别和解决问题。

import inspectclass MyClass:def method(self):pass# 创建对象
obj = MyClass()# 获取对象的标识值
obj_id = id(obj)# 使用 inspect 获取对象的信息
def print_object_info(o):print(f'Object ID: {id(o)}')print(f'Object Type: {type(o)}')print(f'Object Methods: {inspect.getmembers(o, predicate=inspect.ismethod)}')print_object_info(obj)

巧妙用法 3:与 gc 模块结合,用于垃圾回收调试

通过 id() 和 gc 模块,可以检查哪些对象正在被引用,帮助调试内存泄漏问题。

import gcclass MyClass:pass# 创建对象并获取其标识值
obj = MyClass()
obj_id = id(obj)# 强制进行垃圾回收
gc.collect()# 查找所有对象
all_objects = gc.get_objects()# 检查对象是否在被引用
is_in_gc = any(id(o) == obj_id for o in all_objects)
print(f'Object with ID {obj_id} is in GC: {is_in_gc}')

巧妙用法 4:与自定义装饰器结合,实现缓存优化

通过 id() 和装饰器,可以实现基于对象的缓存优化,避免重复计算。

from functools import wrapsdef cache_by_object_id(func):cache = {}@wraps(func)def wrapper(obj, *args, **kwargs):obj_id = id(obj)if obj_id not in cache:cache[obj_id] = func(obj, *args, **kwargs)return cache[obj_id]return wrapperclass ComplexCalculator:def __init__(self, data):self.data = data@cache_by_object_iddef expensive_computation(self):# 假设这是一个耗时的计算result = sum(self.data)print("Computed result:", result)return resultdata = [1, 2, 3, 4, 5]
calculator = ComplexCalculator(data)# 第一次调用会执行计算
result1 = calculator.expensive_computation()# 第二次调用会使用缓存
result2 = calculator.expensive_computation()print(result1 == result2)  # 输出 True

巧妙用法 5:与 __slots__ 结合,优化内存使用

通过 id() 和 __slots__ 特性,可以在对象实例中保存唯一标识符,用于内存优化。

class SlotClass:__slots__ = ('_unique_id',)def __init__(self):self._unique_id = id(self)@propertydef unique_id(self):return self._unique_id# 创建对象
obj = SlotClass()# 获取对象的唯一标识符
print(f'Object Unique ID: {obj.unique_id}')

这些组合使用技巧展示了如何将 id(object) 与其他方法和模块结合,以实现更复杂和巧妙的功能。通过这些示例,可以更深入理解和应用 id(object) 函数。


感谢阅读。

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

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

相关文章

Linux——Linux服务管理

服务管理大作业要求: 基本拓扑如下: 按照要求完成基本的系统管理任务: 完成所有系统的主机名、网络配置; 本次作业共需要3台虚拟机,分别作为客户端、综合应用服务器、存储服务器。三台虚拟机操作系统均为CentOS-Stream…

5.2网安学习第五阶段第二周回顾(个人学习记录使用)

本周重点 ①HIDS的基本应用(suricata) ②Suricata的基本应用 ③Suricata的流量检测 ④Suricata的https流量检测 ⑤利用Elastic整合Suricata日志 ⑥利用Wazuh对Suricata主动响应 本周主要内容 ①HIDS的基本应用(suricata) 1、NIDS 1、定义:网络入侵检测系统…

算法简单笔记

本人大二下学期报了中国大学生计算机设计大赛、珠澳计算机设计大赛、区块链软件设计大赛、蓝桥杯......然后一直准备着设计大赛的比赛,根本没空管蓝桥杯,就省考前准备了一星期,感觉是没有希望了,但是很莫名其妙的就拿了蓝桥杯Java…

通过css实现------简单边框流动特效

效果展示 代码部分 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice…

C++学习/复习5--构造函数与初始化/static成员/友元/内部类/匿名对象/编译器的拷贝构造优化

一、本章概要 二、再谈构造函数 1.构造体赋初值与初始化 2.初始化列表与初始化 2.1定义 2.2注意事项与举例 3.explicit关键字与构造函数 3.1隐式类型转换 也叫做自动类型转换 这种转换通常是从存储范围小的类型到存储范围大的类型&#xff0c;或者是从低精度的数值类型到高…

引入安全生产培训云平台,实现“人人讲安全、个个会应急”

引入安全生产培训云平台&#xff0c;旨在全面提升企业及员工的安全意识与应急处理能力&#xff0c;通过数字化手段实现“人人讲安全、个个会应急”的目标。这一平台的构建和应用&#xff0c;不仅促进了安全知识的普及&#xff0c;还极大提高了培训的效率与效果。以下是该平台几…

驱动开发之字符设备开发

1.概念 字符设备是 Linux 驱动中最基本的一类设备驱动&#xff0c;字符设备就是一个一个字节&#xff0c;按照字节 流进行读写操作的设备&#xff0c;读写数据是分先后顺序的。比如我们最常见的点灯、按键、IIC、SPI&#xff0c; LCD 等等都是字符设备&#xff0c;这些设备的驱…

实验室课程|基于SprinBoot+vue的实验室课程管理系统(源码+数据库+文档)

实验室课程管理系统 目录 基于SprinBootvue的实验室课程管理系统 一、前言 二、系统设计 三、系统功能设计 1管理员功能模块 2学生功能模块 3教师功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介…

elementui中 表格使用树形数据且固定一列时展开子集移入时背景色不全问题(父级和子级所展示的字段是不一样的时候)

原来的效果 修改后实现效果 解决- 需要修改elementui的依赖包中lib/element-ui.common.js中的源码 将js中此处代码改完下面的代码 watch: {// dont trigger getter of currentRow in getCellClass. see https://jsfiddle.net/oe2b4hqt/// update DOM manually. see https:/…

Oracle实践|内置函数之数学型函数

&#x1f4eb; 作者简介&#xff1a;「六月暴雪飞梨花」&#xff0c;专注于研究Java&#xff0c;就职于科技型公司后端工程师 &#x1f3c6; 近期荣誉&#xff1a;华为云云享专家、阿里云专家博主、腾讯云优秀创作者、ACDU成员 &#x1f525; 三连支持&#xff1a;欢迎 ❤️关注…

【Linux安全】Firewalld防火墙基础

目录 一、Firewalld概述 二、Firewalld和iptables的关系 三、Firewalld网络区域 1、firewalld防火墙预定义了9个区域: 2、firewalld 数据包处理原则 3、firewalld数据处理流程 4、firewalld检查数据包的源地址的规则 四、Firewalld防火墙的配置方法 1、firewalld 命令…

SpringBoot项目热部署-解决html修改后需要重启项目的问题

前言&#xff1a;启动热部署之后修改html无需再次重启项目&#xff0c;每次都要重新重启项目 2022IDEA以下版本 1、打开file->Settings->Compiler,勾选Build project automatically 2、按住ctrlshiftalt/ 选Registry进去吧app.running的勾打上、 2022IDEA及以上

NVIDIA Orin/Jetson 平台+数字同轴GMSL 车载AI视觉方案,应用于车载,机器人等领域

专注于成像和视觉技术于近期正式发布了可适配NVIDIA DRIVE AGX Orin平台的一系列摄像头产品&#xff0c;该产品是自主开发的数字同轴GMSL2摄像头模组&#xff0c;可满足智能汽车的高质量成像需求。 目前&#xff0c;推出可适配于NVIDIA DRIVE AGX Orin平台的摄像头产品一共有11…

Modular military character

角色具有31个模块化骨架网格,每个模块具有多个蒙皮: 3个头(4skins) 3件衬衫(9skins) 3条裤子(9skins) 3只靴子(9skins) 7件战术背心(3skins) 4只手和手臂(2skins) 3顶帽子和头盔(9skins) 2个背包(3skins) 3支步枪(3skins) 模块允许您组装超过200万个不同的…

.NET 分享一款多种方式维持权限的工具

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…

第22讲:RBD块存储COW克隆解除父子镜像的依赖关系

RBD块存储COW克隆解除父子镜像的依赖关系 1.COW镜像克隆存在的依赖关系 在前面使用copy-on-write机制基于快照做出来的链接克隆&#xff0c;与快照依赖性很强&#xff0c;如果快照损坏或者丢失&#xff0c;那么克隆的镜像将无法使用&#xff0c;使用这个镜像创建的虚拟机也会…

深度学习模型

深度学习模型 深度学习网络模型是人工智能领域的重要分支&#xff0c;它通过模拟人脑神经网络的工作方式来处理数据并识别模式。以下是对深度学习网络模型的一些主要类型的详细概述&#xff1a; 卷积神经网络&#xff08;Convolutional Neural Network, CNN&#xff09; 结构&a…

MyBatis中的Where标签:提升你的SQL查询效率

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 理解MyBatis的Where标签 MyBatis是一款优秀的持久层框架&#xff0c;它提供了许多强大的标签来帮助编写更优雅、高效的SQL语句。其中&#xff0c;<where>标签是使用频率极高的一个&#xff0c;它能够自动处理…

Mac配置node环境

1.下载nvm(node版本管理工具&#xff0c;同Anaconda对Python的关系&#xff09;。 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash 2.配置vi ~/.zshrc文件&#xff0c;添加如下配置&#xff1a; export NVM_DIR"$HOME/.nvm" [ -…

pytest:指定测试用例执行顺序

在自动化测试中&#xff0c;测试用例的执行顺序有时对测试结果具有重要影响。本文将介绍如何在pytest框架中使用pytest-ordering插件以及Collection hooks来控制测试用例的执行顺序。 方式1&#xff1a; 使用pytest-ordering插件控制执行顺序 1.1 安装pytest-ordering插件 首…