问题描述
根据id()
文档,id
只能保证an是唯一的
- 在特定对象的生命周期内,以及
- 在特定的解释器实例中
因此,(并且与同一Python解释器实例相关联,但是您需要真正尝试使其变为false) )。
正是这样is
做的-
这使得比较id
s是多余的。如果您is
由于某种原因而无法使用语法,那么总会有operator.is_
。
现在, (有时是极 不 -obvIoUs):
例:
>>> class C(object): pass
>>> c=C()
>>> c.a=1
>>> c.a is c.a
True # same object each time
>>> c.__init__ is c.__init__
False # a different object each time
# The above two are not the only possible cases.
# An attribute may be implemented to sometimes return the same object
# and sometimes a different one:
@property
def page(self):
if check_for_new_version():
self._page=get_new_version()
return self._page
-
如果对象 1,之后创建的任何对象都将占用它的
id
。- 在同一代码行中甚至是这样。例如,结果
id(create_foo()) == id(create_bar())
不确定。
- 在同一代码行中甚至是这样。例如,结果
例:
>>> id([]) #the list object is discarded when id() returns
39733320L
>>> id([]) #a new, unrelated object is created (and discarded, too)
39733320L #its id can happen to be the same
>>> id([[]])
39733640L #or not
>>> id([])
39733640L #you never really kNow
由于比较id
s时的上述安全性要求,因此用aid
代替对象不是很有用,因为无论如何您都必须保存对对象本身的引用-
以确保它保持活动状态。也没有任何性能提升:is
实现就像比较指针一样简单。
最后,作为内部优化(和实现细节,因此实现和发行版之间可能会有所不同),cpython重用了一些经常使用的不可变类型的简单对象。在撰写本文时,其中包括小整数和一些字符串。因此,即使您从不同的地方获得它们,它们的id
s也会重合。
这(在技术上)没有违反上述id()
文档的唯一性保证:重用的对象在所有重用中都保持活动状态。
这也不是什么大问题,因为两个变量是否指向同一个对象只知道该对象是否可变:[如果两个变量指向同一个可变对象,那么改变一个变量(意外地)也会改变另一个变量。不可变类型没有这个问题,因此对于它们来说,两个变量指向两个相同的对象还是指向同一对象都没有关系。
1有时,这称为“未命名表达式”。
解决方法
id()
在实践中我可以在多大程度上依赖对象及其唯一性?例如:
- 是否
id(a) == id(b)
意味着a is b
反之亦然?那相反呢? - 保存某个
id
地方以后使用(例如,放入某个注册表而不是对象本身)有多安全?
(作为针对Python规范的建议规范编写:是具有相同id()相同对象的对象,是is运算符,未绑定方法对象