当前位置:   article > 正文

Python-VBA函数之旅-id函数

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. # 1.函数:id
  2. # 2.功能:用于获取对象的内存地址
  3. # 3.语法:id(object)
  4. # 4.参数:object,对象
  5. # 5.返回值:一个整数,返回对象的内存地址
  6. # 6.说明:
  7. # 6-1、返回一个整数,在此对象的生命周期中保证是唯一且恒定的
  8. # 6-2、两个生命期不重叠的对象可能具有相同的id()值
  9. # 7.示例:
  10. # 应用1:调试和内存管理
  11. # 理解对象身份
  12. # 创建两个相同的整数对象
  13. a = 10
  14. b = 10
  15. # 打印它们的id
  16. print(f"ID of a: {id(a)}")
  17. print(f"ID of b: {id(b)}")
  18. # 由于Python对小的整数进行了缓存,所以a和b可能指向同一个对象
  19. # 因此,它们的id可能相同
  20. # ID of a: 140715802354760
  21. # ID of b: 140715802354760
  22. # 理解对象赋值
  23. # 创建一个列表对象
  24. list1 = [3, 5, 6]
  25. print(f"ID of list1: {id(list1)}")
  26. # 将list1赋值给list2
  27. list2 = list1
  28. print(f"ID of list2: {id(list2)}")
  29. # list1和list2指向同一个对象,所以它们的id相同
  30. # ID of list1: 2581367673280
  31. # ID of list2: 2581367673280
  32. # 理解对象复制
  33. # 创建一个列表对象
  34. list1 = [3, 5, 6]
  35. print(f"ID of list1: {id(list1)}")
  36. # 使用切片操作复制list1
  37. list2 = list1[:]
  38. print(f"ID of list2: {id(list2)}")
  39. # list2是list1的一个新副本,所以它们有不同的id
  40. # ID of list1: 2333963122432
  41. # ID of list2: 2333963122560
  42. # 理解对象在内存中的变化
  43. # 创建一个列表对象
  44. list1 = [3, 5, 6]
  45. print(f"ID of list1 before modification: {id(list1)}")
  46. # 修改列表
  47. list1.append(8)
  48. print(f"ID of list1 after modification: {id(list1)}")
  49. # 修改列表不会改变它的id,因为列表对象在内存中的位置没有改变
  50. # 只是列表的内容发生了变化
  51. # ID of list1 before modification: 2302696935872
  52. # ID of list1 after modification: 2302696935872
  53. # 应用2:检查对象是否相同
  54. # 检查两个整数是否指向相同的对象
  55. a = 123
  56. b = 123
  57. # 使用id()函数检查它们的身份是否相同
  58. if id(a) == id(b):
  59. print("a 和 b 指向相同的对象")
  60. else:
  61. print("a 和 b 指向不同的对象")
  62. # 对于小的整数,Python通常会缓存它们,所以a和b可能指向相同的对象
  63. # 但是,这并非总是如此,所以这种方法并不完全可靠来检查整数值是否相等
  64. # a 和 b 指向相同的对象
  65. # 检查两个列表是否指向相同的对象
  66. list1 = [1, 2, 3]
  67. list2 = list1 # list2是list1的引用,它们指向同一个对象
  68. list3 = [1, 2, 3] # list3是一个新的列表对象,与list1内容相同但身份不同
  69. # 使用id()函数检查它们的身份
  70. if id(list1) == id(list2):
  71. print("list1 和 list2 指向相同的对象")
  72. else:
  73. print("list1 和 list2 指向不同的对象")
  74. if id(list1) == id(list3):
  75. print("list1 和 list3 指向相同的对象")
  76. else:
  77. print("list1 和 list3 指向不同的对象")
  78. # 在这个例子中,list1和list2指向同一个对象,而list1和list3指向不同的对象,尽管它们的内容相同
  79. # list1 和 list2 指向相同的对象
  80. # list1 和 list3 指向不同的对象
  81. # 使用is运算符检查对象身份
  82. if list1 is list2:
  83. print("list1 is list2(它们指向相同的对象)")
  84. else:
  85. print("list1 is not list2")
  86. if list1 is list3:
  87. print("list1 is list3(它们指向相同的对象)")
  88. else:
  89. print("list1 is not list3")
  90. # is运算符是检查对象身份更直接、更常见的方法
  91. # list1 is list2(它们指向相同的对象)
  92. # list1 is not list3
  93. # 应用3:单例模式实现
  94. class Singleton:
  95. _instance = None
  96. def __new__(cls, *args, **kwargs):
  97. if not cls._instance:
  98. cls._instance = super(Singleton, cls).__new__(cls)
  99. return cls._instance
  100. def __init__(self, value):
  101. self.value = value
  102. # 创建第一个实例
  103. singleton1 = Singleton(42)
  104. print(f"ID of singleton1: {id(singleton1)}")
  105. # 尝试创建第二个实例
  106. singleton2 = Singleton(24)
  107. print(f"ID of singleton2: {id(singleton2)}")
  108. # 检查两个实例是否相同
  109. if singleton1 is singleton2:
  110. print("singleton1 and singleton2 are the same instance")
  111. else:
  112. print("singleton1 and singleton2 are different instances")
  113. # 使用id()函数进一步验证
  114. if id(singleton1) == id(singleton2):
  115. print("ID of singleton1 and singleton2 are the same")
  116. else:
  117. print("ID of singleton1 and singleton2 are different")
  118. # ID of singleton1: 2438427103696
  119. # ID of singleton2: 2438427103696
  120. # singleton1 and singleton2 are the same instance
  121. # ID of singleton1 and singleton2 are the same
  122. # 应用4:缓存和重用对象
  123. class ObjectCache:
  124. def __init__(self):
  125. self.cache = {}
  126. def get_or_create(self, key, creator_function, *args, **kwargs):
  127. """
  128. 根据key获取对象,如果不存在则使用creator_function创建并缓存。
  129. """
  130. if key not in self.cache:
  131. # 调用creator_function创建新对象,并传入额外的参数
  132. new_object = creator_function(*args, **kwargs)
  133. # 将新对象添加到缓存中
  134. self.cache[key] = new_object
  135. # 返回缓存中的对象
  136. return self.cache[key]
  137. # 示例:创建一个缓存对象
  138. cache = ObjectCache()
  139. # 假设我们有一个创建对象的函数
  140. def create_expensive_object(id):
  141. print(f"Creating object with ID: {id}")
  142. # 这里模拟创建一个昂贵的对象(比如从数据库加载或执行复杂计算)
  143. return f"Object {id}"
  144. # 尝试获取一个ID为1的对象
  145. obj1 = cache.get_or_create('1', create_expensive_object, '1')
  146. print(f"Object with ID 1: {obj1}")
  147. # 再次尝试获取ID为1的对象,这次应该直接从缓存中获取
  148. obj2 = cache.get_or_create('1', create_expensive_object, '1')
  149. print(f"Object with ID 1 (cached): {obj2}")
  150. # 检查两个对象是否相同(实际上是缓存中的同一个对象)
  151. print(f"obj1 is obj2: {obj1 is obj2}")
  152. # 尝试获取一个ID为2的新对象
  153. obj3 = cache.get_or_create('2', create_expensive_object, '2')
  154. print(f"Object with ID 2: {obj3}")
  155. # Creating object with ID: 1
  156. # Object with ID 1: Object 1
  157. # Object with ID 1 (cached): Object 1
  158. # obj1 is obj2: True
  159. # Creating object with ID: 2
  160. # Object with ID 2: Object 2
1-2、VBA
略,待后补。
2、推荐阅读:

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

Python算法之旅:Algorithm

Python函数之旅:Functions 

个人主页:神奇夜光杯-CSDN博客 
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/547244
推荐阅读
相关标签
  

闽ICP备14008679号