Unexpected result when comparing method with variable

Michael Spencer mahs at telcopartners.com
Mon Apr 4 23:53:15 EDT 2005


David Handy wrote:
> I had a program fail on me today because the following didn't work as I
> expected:
> 
> 
>>>>class C:
> 
> ...     def f(self):
> ...         pass
> ...
> 
>>>>c = C()
>>>>m = c.f
>>>>m is c.f
> 
> False
> 
> I would have expected that if I set a variable equal to a bound method, that
> variable, for all intents and purposes, *is* that bound method, especially
> since I hadn't changed or deleted anything on the class or its instance.
> 
> The same thing happens when attempting to compare an unbound method with a
> variable name bound to that unbound method:
> 
> 
>>>>M = C.f
>>>>M is C.f
> 
> False
> 
> If I were to guess what is going on here, I would say that the expression
> c.f invokes a descriptor that manufactures a brand new "method object" each
> time.  

Yes, I believe that's the case.  See Martelli's recent 'Black Magic' PyCon 
presentation for some details of what's going on, but IIRC, the essence is that 
a bound method is produced by calling __get__ on the function, with the 
class/instance as the argument

The problem is, this is non-intuitive (to me) and prevented me from
> doing something I thought was useful.

Agreed that:
  >>> class C(object):
  ...     def f(self):pass
  ...
  >>> C.f is C.f
  False

is surprising
> 
> My use case is deferring operations till later, by placing tuples of a
> method and its arguments in a list to be processed at some future time, but
> doing some special-case processing only for certain methods:
> 
> deferred = []
> ...
> deferred.append((c.f, ('abc', 123)))
> 
> ...
> 
> for method, params in deferred:
>     method(*params)
>     if method is c.f:
>         # handle a special case
> 
> But I can't do that special-case handling this way, I have to resort to some
> other means to identify a method, "method is c.f" is always False. Which
> seems strange to me.

Another workaround is to compare method.im_func which does pass the identity test
...
> 
> If I complain about this, would I get any sympathy? ;)
> 
Sympathy, sure ;-)

> 
Michael




More information about the Python-list mailing list