Reputation: 8778
I have the following script:
class A(object):
def f(self):
pass
a = A()
b = A()
print map(id, [A.f, a.f, b.f])
print map(id, [a.f, b.f])
Out:
[4299312976, 4298026672, 4299370816]
[4299312976, 4298026672]
id
of A.f
become the id
of a.f
?id
of a.f
become the id
of b.f
?Now I do this:
print "{0} {1} {2}".format(id(A.f), id(a.f), id(b.f))
Out:
4299312976 4299312976 4299312976
Why do they have the same id
now?
Upvotes: 3
Views: 87
Reputation: 114461
When you access A.f
an object is created, of type <unbound method>
. You can see this is the case with:
print map(id, [A.f, A.f, A.f])
where the id
value won't be the same. The same happens for a.f
and b.f
but in this case the type is <bound method>
because the object remembers which instance the code needs to act on.
These objects are garbage collected once you don't reference them any more. So:
map(id, [A.f, a.f, b.f])
creates 3 objects (4 including the list containing them) and passes them to the function id
. Once the map
call is terminated list and the objects are collected and memory is freed.
In the second call new objects are created and the memory for the object created for A.f
has been reused (thus you get he same id
).
In the last example you're calling id
each time explicitly on an object that is immediately discarded, and the memory happens to be reused immediately.
This apparently "magical" object creation when accessing a method happens because of descriptors.
Upvotes: 4