What is "self"?

Michael Spencer mahs at telcopartners.com
Fri Sep 23 14:55:39 EDT 2005


Ron Adam wrote:
> Erik Max Francis wrote:
> 
>>Ron Adam wrote:
>>
>>
>>>When you call a method of an instance, Python translates it to...
>>>
>>>     leader.set_name(leader, "John")
>>
>>
>>It actually translates it to
>>
>>    Person.set_name(leader, "John")
>>
> 
> 
> I thought that I might have missed something there.
> 
> Is there a paper on how python accesses and stores instance data and 
> methods?  I googled but couldn't find anything that addressed this 
> particular question.
> 
>  >>> class a(object):
> ...    def x(self):
> ...       print 'x'
> ...
>  >>> b = a()
>  >>> b
> <__main__.a object at 0x009D1890>
>  >>> b.x
> <bound method a.x of <__main__.a object at 0x009D1890>>
> 
> So what exactly is a bound method object?  Does it possibly translates 
> to something like the following?
> 
>      def x(*args, **kwds):
>          self = ?
>          return __class__.self(self, *args, **kwds)
> 
> Cheers,
> Ron
> 
> 
> 
> 
> 

All is explained at:
http://users.rcn.com/python/download/Descriptor.htm#functions-and-methods
and further at:
http://www.python.org/pycon/2005/papers/36/pyc05_bla_dp.pdf

"For objects, the machinery is in object.__getattribute__ which transforms b.x 
into type(b).__dict__['x'].__get__(b, type(b))."

What follows is my interpretation - hope it's correct:

# what exactly is a bound method object?
# Illustrate b.f => type(b).__dict__['x'].__get__(b, type(b))

  >>> class B(object):
  ...     def f(self, x):
  ...         return x or 42
  ...
  >>> b = B()
  >>> type(b).__dict__['f']
  <function f at 0x015052B0>  # a plain old function
  >>> _.__get__(b, type(b))   # invoke the descriptor protocol
                              # to make a bound method
  <bound method B.f of <Untitled7.B object at 0x01843D70>>
  >>>

You don't have to use object.__getattribute__ to get a bound method.  Nor does 
the function have to be in the class dictionary.  You can just call any function 
descriptor yourself:

  >>> def g(self, y):
  ...     return self.f(y)
  ...
  >>> boundg = g.__get__(b)  # bind to B instance
  >>> boundg
  <bound method ?.g of <Untitled7.B object at 0x01843D70>>
  >>> boundg(0)
  42
  >>>

Looked at this way, function.__get__ just does partial function application (aka 
currying).

  >>> def f(x, y):
  ...     return x+y
  ...
  >>> add42 = f.__get__(42)
  >>> add42
  <bound method ?.f of 42>
  >>> add42(1)
  43


Michael




More information about the Python-list mailing list