Python a==b为假,但id(a)==id(b)为真?
遇到以下情况:Python a==b为假,但id(a)==id(b)为真?,python,object,methods,overriding,Python,Object,Methods,Overriding,遇到以下情况: >>> class A: ... def __str__(self): ... return "some A()" ... >>> class B(A): ... def __str__(self): ... return "some B()" ... >>> print A() some A() >>> print B() some B()
>>> class A:
... def __str__(self):
... return "some A()"
...
>>> class B(A):
... def __str__(self):
... return "some B()"
...
>>> print A()
some A()
>>> print B()
some B()
>>> A.__str__ == B.__str__
False # seems reasonable, since each method is an object
>>> id(A.__str__)==id(B.__str__)
True # what?!
这里发生了什么事?以下工作:
>>> id(A.__str__.im_func) == id(A.__str__.im_func)
True
>>> id(B.__str__.im_func) == id(A.__str__.im_func)
False
当字符串id(A.\uu str\uuuuuuu)==id(B.\uu str\uuuuuuuuu)
被计算时,A.\uu str\uuuuuuu
被创建,其id被获取,然后被垃圾收集。然后创建B.。\uuuu str\uuuuu
,并且恰好在A.\uuu str\uuuuu
之前的地址处结束,因此它(在CPython中)获得相同的id
尝试将A.\uuuu str\uuu
和B.\uu str\uuu
分配给临时变量,您将看到不同的结果:
>>> f = A.__str__
>>> g = B.__str__
>>> id(f) == id(g)
False
有关此现象的更简单示例,请尝试:
>>> id(float('3.0')) == id(float('4.0'))
True
对于我们这些被您的标题吸引的人来说,要确定某个方法是否被覆盖:
class A:
def __str__(self):
return "some A()"
def strWasOverridden(self):
return A.__str__ != self.__str__
但是,为什么>>>f=A.uu str_u>>>id(f)==id(A.uu str_uuu)False@jldupont:Python在运行时创建未绑定的方法
A.\uu str\uu
和B.\uu str\uu
。对于底层机制是一个很好的参考。。。那些垃圾能这么快收集起来吗?我仍然不相信这个解释。@jldupont,CPython被重新计数,所以大多数东西都会立即被垃圾收集。这是对发生的事情的正确解释。@jldupont:这个理论很容易验证!尝试创建float的子类myfloat
,并覆盖\uuuuu new\uuuuu
和\uu del\uuuuu
,以便它们适当地记录调用。现在,观察计算id(myfloat(1.0))==id(myfloat(2.0))
时的操作顺序。(并不是说对\uu del\uuu
的调用必然直接对应于垃圾收集。)实际上,不是。这总是正确的,因为方法上的实例永远不等于类上的方法。