I've noticed that sometimes instance methods do not compare as identical (using is
rather than ==
), even when they relate to the same bound instance method e.g.
>>> class A(object):
... def f(self):
... print "hi"
...
>>> a = A()
>>> f1 = a.f
>>> f2 = a.f
>>> f1 is f2
False
>>> f1 == f2
True
I've ended up using ==
to check to see if two variables refer to the same bound method, but I was wondering if anyone knew why is
does not behave as I would expect?
methods are implemented as descriptors -- So each time you access the f
member, a new function is created. You can see this by looking at their ids...
>>> class A(object):
... def f(self):
... pass
...
>>> a = A()
>>> f1 = a.f
>>> f2 = a.f
>>> id(f1)
4325305232
>>> id(f2)
4325818528
To be a little more clear what I mean when I say that they are implemented via descriptors, the following expressions:
a = A()
func = a.f
are equivalent to:
a = A()
func = A.f.__get__(a, A)
Clearly you don't want to be writing the latter all the time, so the shortcut is pretty nice :-).
With that said, this starts to explain how a bound method knows what self
is since a
(which is self
in the method) gets passed to __get__
which is what constructs the bound method.