Another of those "is" issues.

Bruno Desthuilliers bdesth.quelquechose at
Sat Mar 21 19:42:41 CET 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 

> 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