为什么id(A())== id(A())与A()不同是A()?

nev*_*sly 6 python

我对下面的python代码很困惑:

>>> class A(): pass  
...  
>>> id(A()) == id(A())  
True  
>>> id(A())  
19873304  
>>> id(A())  
19873304
>>> A() is A()
False
>>> a = A()
>>> b = A()
>>> id (a) == id (b)
False
>>> a is b
False
>>> id (a)
19873304
>>> id (b)
20333272
>>> def f():
...     print id(A())
...     print id(A())
...
>>> f()
20333312
20333312
Run Code Online (Sandbox Code Playgroud)

我可以清楚地告诉自己在创建对象时python正在做什么.
谁能告诉我更多关于发生了什么的事情?谢谢!

Cha*_*ffy 5

两个不同的对象可以位于内存中的相同位置,如果其中一个在创建另一个之前被释放.

也就是说 - 如果你分配一个对象,获取它的id,然后不再引用它,它就可以被释放,所以另一个对象可以获得相同的id.

相反,如果保留对第一个对象的引用,则分配的任何后续对象都必须具有不同的id.


the*_*eye 5

当你说

print id(A()) == id(A())
Run Code Online (Sandbox Code Playgroud)

您正在创建一个类型的对象A并将其传递给id函数.当函数返回时,没有对为参数创建的对象的引用.因此,引用计数变为零,并且它已准备好进行垃圾回收.

当您id(A())再次使用相同的表达式时,您正在尝试创建另一个相同类型的对象.现在,Python可能会尝试重用与之前创建的对象相同的内存位置(如果它已经被垃圾回收).否则它将在不同的位置创建它.所以,id可能是也可能不一样.

如果你拿,

print A() is A()
Run Code Online (Sandbox Code Playgroud)

我们创建了一个类型的对象,A我们试图将它与另一个类型的对象进行比较A.现在,第一个对象仍在此表达式中引用.因此,它不会标记为垃圾收集,因此引用将始终不同.

建议:切勿在生产代码中执行此类操作.

引用文档,

由于自动垃圾收集,空闲列表和描述符的动态特性,您可能会注意到is运算符的某些使用中看似异常的行为,如涉及实例方法或常量之间的比较.查看他们的文档了解更多信息.