为什么(酸(A())与A()不同是A()?

时间:2014-02-13 03:48:09

标签: 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

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

4 个答案:

答案 0 :(得分:5)

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

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

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

答案 1 :(得分:5)

当你说

print id(A()) == id(A())

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

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

如果你采取,

print A() is A()

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

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

引自docs

  

由于自动垃圾收集,免费列表和动态   描述符的性质,你可能会注意到看似不寻常的行为   运算符的某些用法,如涉及比较的那些   实例方法或常量之间。检查他们的文档   更多信息。

答案 2 :(得分:0)

A()创建一个临时变量,然后将其清除

所以下一个A()得到相同的id(这只是垃圾收集,虽然这种行为可能无法保证))...因此当你打印它们时它们具有相同的id

id(A()) == id(A())

必须创建两个临时变量,每个变量具有不同的id

答案 3 :(得分:0)

由于id()基于对象指针,因此只有两个对象都在内存中时,才能保证它是唯一的。在某些情况下,A的第二个实例可能会在第一个实例的内存中重复使用相同的位置(已经被垃圾收集)。