2010-02-23 6 views
13

Столкнулся следующее:a == b является ложным, но id (a) == id (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?! 

Что здесь происходит?

ответ

8

следующие работы:

>>> id(A.__str__.im_func) == id(A.__str__.im_func) 
True 
>>> id(B.__str__.im_func) == id(A.__str__.im_func) 
False 
+0

Примечание: этот ответ работает только на Python 2. – BenC

11

В строке id(A.__str__) == id(B.__str__) оценивается, A.__str__ создан, его идентификатор берется, а затем сбор мусора. Затем создается B.__str__ и, случается, заканчивается тем же адресом, что и A.__str__, поэтому он получает (в CPython) один и тот же идентификатор.

Попробуйте назначить A.__str__B.__str__ и для временных переменных, и вы увидите что-то другое:

>>> f = A.__str__ 
>>> g = B.__str__ 
>>> id(f) == id(g) 
False 

Для более простого примера этого явления, попробуйте:

>>> id(float('3.0')) == id(float('4.0')) 
True 
+0

Но тогда, почему >>> е = A .__ str__ >>> идентификатор (е) == Идентификатор (A .__ str__) Ложные – Krab

+0

'А. __str__' создан ??? Не уверен в этом: он должен быть частью метакласса, который порождает все классы, т. Е. Их основную «ДНК». – jldupont

+2

@jldupont: Python создает несвязанные методы 'A .__ str__' и' B .__ str__' во время выполнения. http://users.rcn.com/python/download/Descriptor.htm - хорошая ссылка для основных механизмов. –

0

Для тех из нас привлекает по вашему названию, чтобы определить, был ли переопределен метод:

class A: 
    def __str__(self): 
     return "some A()" 

    def strWasOverridden(self): 
     return A.__str__ != self.__str__ 
+0

Собственно, нет. Это всегда верно, потому что экземпляр метода никогда не равен методу в классе. –

Смежные вопросы