Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python id of function of instance is inconsistent

Please consider the following

class A(object):
    def foo(self):
        pass


a = A()
# accessing a's foo seems consistent
init1 = a.foo
init2 = a.foo
assert init1 == init2
assert id(a.foo) == id(a.foo)

# Or is it?
foos= [a.foo for i in range(10)]
ids = [id(foo) for foo in foos]
for i, id_ in enumerate(ids):
    for j, id__ in enumerate(ids):
        if i != j:
            assert id_ != id__

It appears id(a.foo) can equal to id(a.foo) and can not equal to id(a.foo), but I can't understand when it is the same and when it isn't.

Please explain what's going on here.

like image 937
Gulzar Avatar asked Apr 24 '26 00:04

Gulzar


1 Answers

The transformation of a function to an instance method happens every time the instance method attribute is accessed, so the id should be different every time, at least in the sense that a new object has been created. (see Python Data Model for details about method transformation and descriptors)

The problem is doing this:

assert id(a.foo) == id(a.foo)

There are times the Python garbage collector can work so fast that even within a single expression, two different objects can have the same id, because the object has already been reclaimed once id() is done with it.

If you do this:

assert id(init1) == id(init2)

you'll see that they in fact have different ids.


Update: to address the question about why init1 == init2 is True: init1 and init2 are method wrapper objects that refer to the same function in the same class, so the method wrapper's __eq__() considers them equal.

like image 171
sj95126 Avatar answered Apr 25 '26 13:04

sj95126



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!