Another of those "is" issues.
Bruno Desthuilliers
bdesth.quelquechose at free.quelquepart.fr
Sat Mar 21 14:42:41 EDT 2009
Emanuele D'Arrigo a écrit :
> Hi everybody,
>
> I was unit testing some code today and I eventually stumbled on one of
> those "is" issues quickly solved replacing the "is" with "==". Still,
> I don't quite see the sense of why these two cases are different:
>
>>>> def aFunction():
> ... pass
> ...
>>>> f = aFunction
>>>> f is aFunction
> True <--- Ok, this seems reasonable. Nevertheless, I suspect I
> shouldn't quite rely on it.
And you're wrong.
>>>> class MyClass(object):
> ... def myMethod(self):
> ... pass
> ...
>>>> c = MyClass()
>>>> m = c.myMethod
>>>> m is c.myMethod
> False <--- What? Why is that?
c.myMethod resolves to MyClass.__dict['myMethod'].__get__(c), which
returns a new Method object.
> In my mind I was expecting that when the method
> is assigned to "m" all
> that it happens is that its address is assigned to the name "m" so
> that effectively the same address is now pointed to by two names, like
> in the function case.
The "m = c.myMethod" statement effectively binds name "m" to a Method
instance. What you don't get is what really is a Method object.
You assume that the "def" statement behaves differently when used within
a "class" statement - which is just not the case. The "def" statement
_always_ create a function object. Just try this:
print type(MyClass.__dict__["myMethod"])
print type(MyClass.myMethod)
print type(c.myMethod)
What happens here is that the function type implements the descriptor
protocol in such a way to return a Method object (a callable object
wrapping the function and instance - IOW, a partial application of
MyClass.__dict__["myMethod"] and 'c') when resolved as a class
attribute. So each time you evaluate c.myMethod, you get a new Method
object.
> I googled around for some hint but I wouldn't
> exactly say I'm clear on the issue just yet...
>
> Can anybody shed some light? Or point to a resource to look at?
I lost track of how many times I explained this on this newsgroup - but
googling for +method +descriptor +"lookup rules" should yield some results.
> Or
> what's the bit of python's source code that is responsible for dealing
> with those assignments?
It has nothing to do with assignement - it's about attributes lookup rules.
More information about the Python-list
mailing list