How to get a unique id for bound methods?

Bengt Richter bokr at oz.net
Fri Aug 19 17:42:47 EDT 2005


On Fri, 19 Aug 2005 13:29:19 -0700, "Russell E. Owen" <rowen at cesmail.net> wrote:

>I have several situations in my code where I want a unique identifier 
>for a method of some object (I think this is called a bound method). I 
>want this id to be both unique to that method and also stable (so I can 
>regenerate it later if necessary).
>

>I thought the id function was the obvious choice, but it doesn't seem to 
>work. The id of two different methods of the same object seems to be the 
>same, and it may not be stable either. For instance:
>
The id function works, but you are applying it to transient objects, which
is what bound methods are unless you cause them to persist one way or another.

>class cls(object):
>  def __init__(self):
>    print id(self.meth1)
>    print id(self.meth2)
>  def meth1(self):
>    pass
>  def meth2(self):
>    pass
>
>c = cls()
>3741536
>3741536
This means that self.meth1 only existed long enough to be passed to id,
and when id was done with determining its id, self.meth1 was freed.
Then self.meth2 was created, and happened to use a representation space
with the same id as was used for self.meth1. If the two objects (bound methods
here) existed at the same time, they would be guaranteed not to have the same id
unless they were actually the same object.

>print id(c.meth1)
>3616240
>print id(c.meth2)
>3616240
This happened to re-use a representation space with another id.
>
>I guess that just means bound methods aren't objects in their own right, 
>but it surprised me.
No, they are objects in their own right. You were surprised by your
[mis]interpretation of the above results ;-)
>
>The "hash" function looks promising -- it prints out consistent values 
>if I use it instead of "id" in the code above. Is it stable and unique? 
>The documentation talks about "objects" again, which given the behavior 
>of id makes me pretty nervous.
>
>Any advice would be much appreciated.
>
If you want a particular bound method to have a stable and persistent id,
make it persist, e.g.,

 >>> class cls(object):
 ...   def __init__(self):
 ...     print id(self.meth1)
 ...     print id(self.meth2)
 ...   def meth1(self):
 ...     pass
 ...   def meth2(self):
 ...     pass
 ...
 >>> c = cls()
 49219060
 49219060
 >>> print id(c.meth1)
 49219020
 >>> print id(c.meth2)
 49219020

Ok, those were transient, now nail a couple of bound methods down:
 >>> cm1 = c.meth1
 >>> cm2 = c.meth2

And you can look at their id's all you like:

 >>> print id(cm1)
 49219020
 >>> print id(cm2)
 49219060
 >>> print id(cm1)
 49219020
 >>> print id(cm2)
 49219060

But every time you just evaluate the attribute expression c.meth1 or c.meth2
you will get a new transient bound method object, with a new id:

 >>> print id(c.meth1)
 49219180
 >>> print id(c.meth2)
 49219180

But the ones we forced to persist by binding the expression values to cm1 and cm2
above still have the same ids as before:

 >>> print id(cm1)
 49219020
 >>> print id(cm2)
 49219060

So the question would be, why do you (think you ;-) need ids for
these bound methods as such? I.e., what is the "situation" in your code?

Regards,
Bengt Richter



More information about the Python-list mailing list