Reputation: 26668
I was actually going through descriptors python docs and came across this example
>>> class D(object):
def f(self, x):
return x
>>> d = D()
>>> D.__dict__['f'] # Stored internally as a function
<function f at 0x00C45070>
>>> id(D.__dict__['f']) # Memory location
49294384
>>> D.f # Get from a class becomes an unbound method
<unbound method D.f>
>>> id(D.f )
48549440
>>> d.f # Get from an instance becomes a bound method
<bound method D.f of <__main__.D object at 0x00B18C90>>
>>> id(d.f)
48549440
So from the above code, I understood that python stores the function definition/declaration
of a class as a separate object internally inside class __dict__
variable, when we access directly using __dict__
variable it has memory location as 49294384
But why does it is showing as different function/method object with different memory location 48549440
when accessed through Class or Object?
like D.f and d.f
was it not supposed to refer to the same object when we access using the __dict__
variable?. If so why?
Upvotes: 3
Views: 71
Reputation: 11280
xtofi explained the difference between descriptor objects (unbound) and bound methods.
I think the missing part is that bound methods are not kept in memory, and they are actually created every time you access them. (You may get the same memory location, but it's not the same object).
Why? Because on every call on a descriptor may result in a different behavior. Here is an example to explain this idea.
class A(object):
i = 'a'
@property
def name(self):
if A.i == 'a':
return self.fa()
else:
return self.fb()
def fa(self):
print 'one function'
def fb(self):
print 'another function'
Calling the function name
on an instance of A results in different function calls.
Upvotes: 0
Reputation: 41509
D.f
is a function taking one argument (self
)
x = D.f
x(d)
d.f
is a "bound method", i.e. a function where the self
argument has already been filled in. You can say
x = d.f
x()
Therefor it cannot be the same thing as D.f
, and has to be on a different location.
Upvotes: 2