pythonobjectmethods

Why do methods of different objects of same class have same id?


In the following code, I don't understand why useless_func has the same id when it belongs to two different objects?

class parent(object):
   @classmethod
   def a_class_method(cls):
     print "in class method %s" % cls

   @staticmethod
   def a_static_method():
     print "static method"

   def useless_func(self):
     pass

 p1, p2 = parent(),parent()

 id(p1) == id(p2) // False

 id(p1.useless_func) == id(p2.useless_func) // True

Solution

  • Here is what I think is happening:

    1. When you dereference p1.useless_func, a copy of it is created in memory. This memory location is returned by id
    2. Since there are no references to the copy of the method just created, it gets reclaimed by the GC, and the memory address is available again
    3. When you dereference p2.useless_func, a copy of it is created in the same memory address (it was available), which you retrieve using id again.
    4. The second copy is GCd

    If you were to run a bunch of other code and check the ids of the instance methods again, I'll bet the ids would be identical to each other, but different from the original run.

    Additionally, you might notice that in David Wolver's example, as soon as a lasting reference to the method copy is obtained the ids become different.

    To confirm this theory, here is a shell session using Jython (same result with PyPy), which does not utilize CPython's reference counting garbage collection:

    Jython 2.5.2 (Debian:hg/91332231a448, Jun 3 2012, 09:02:34) 
    [OpenJDK Server VM (Oracle Corporation)] on java1.7.0_21
    Type "help", "copyright", "credits" or "license" for more information.
    >>> class parent(object):
    ...     def m(self):
    ...             pass
    ... 
    >>> p1, p2 = parent(), parent()
    >>> id(p1.m) == id(p2.m)
    False