id() vs `is` operator. Is it safe to compare `id`s? Does the same `id` mean the same object?
我能在多大程度上依赖对象的
id(a) == id(b) 是指a is b 还是相反?相反呢?- 把一个
id 保存到以后使用的地方(例如保存到某个注册表而不是对象本身)有多安全?
(作为响应Python规范的建议规范编写:are objects with the same id()the same object,`is` operator,unbound method objects)
根据
因此,比较
这正是
现在,一个对象在比较时是否还活着并不总是显而易见的(有时是非常不明显的):
每次访问一些属性(例如对象的绑定方法)都会创建一个新对象。因此,结果的
id 在每个属性访问上可能相同,也可能不同。例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18>>> 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()) 的结果未定义。例子:
1
2
3
4
5
6
7
8>>> 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
在比较
最后,作为一个内部优化(和实现细节,因此在实现和发布之间可能有所不同),CPython重用了一些经常使用的不可变类型的简单对象。在写这篇文章时,它包括小整数和一些字符串。所以,即使你从不同的地方得到它们,它们的
这不会(技术上)违反上述
这也没什么大不了的,因为两个变量是否指向同一个对象才是了解对象是否可变的实用方法:如果两个变量指向同一个可变对象,则一个变量的变化(意外)也会改变另一个变量。不可变类型没有这个问题,所以对于它们来说,两个变量指向两个相同的对象或同一个对象并不重要。
有时,这称为"未命名表达式"。