Reputation: 81
How come function x can access the "self" of some object it's not part of??? See the following code:
#!/usr/bin/env python
class A(object):
def __init__(self):
self.a = 1
def doit(self):
print self.a
a = A()
x = a.doit
x()
See:
$ ./classes.py
1
$
Upvotes: 1
Views: 75
Reputation: 156188
when you use instance.attr
, and the attribute is a function, python does something extra; it returns the function as a "method", with the self
parameter preset to the instance. In the case that you instead do someclass.attr
; the same attribute but on a class instead of an instance of the class; python will still return a method, but without binding self
.
>>> class A(object):
... def __init__(self):
... self.a = 1
... def doit(self):
... print self.a
...
>>> A
<class '__main__.A'>
The method, as accessed from the class
>>> A.doit
<unbound method A.doit>
>>> print repr(A.doit.im_self)
None
self
not yet bound to anything
An instance of A
>>> a = A()
>>> a
<__main__.A object at 0x7fa13456ca50>
self
is bound for a.doit
>>> a.doit
<bound method A.doit of <__main__.A object at 0x7fa13456ca50>>
>>> print repr(a.doit.im_self)
<__main__.A object at 0x7fa13456ca50>
it's the same object:
>>> a.doit.im_self is a
True
Upvotes: 0
Reputation: 82028
It has to do with something call binding
. The short and stupid explanation: the method will "remember" (it is bound to) where it was created and operate in that context.
The longer explanation goes into how closures are doing the same thing, and it does things like cites Alonzo Church and some pretty nifty stuff like locally defined functions and classes. But the long and the short will always be that it is simply recalling its context.
Upvotes: 1
Reputation: 35993
If you call x()
, it simply resolves to calling a.doit()
, which is no problem at all to access the contents of A
.
Upvotes: 4