What is "self"?

Ron Adam rrr at ronadam.com
Tue Sep 27 18:11:54 CEST 2005


Diez B. Roggisch wrote:
>> This still seems not quite right to me...  Or more likely seems to be 
>> missing something still.
>>
>> (But it could be this migraine I've had the last couple of days 
>> preventing me from being able to concentrate on things with more than 
>> a few levels of complexity.)
>>
>> Playing around with the shell a bit gives the impression that calling 
>> a method in a instance gives the following (approximate) result...
>>
>>     try:
>>         leader.__dict__["set_name"]("John")
>>     except:
>>         type(leader).__dict__["set_name"].__get__(leader, "John")
>>         # which results in...
>>         #    Person.set_name(leader, "John")
>>     except:
>>         raise( AttributeError,
>>                "%s object has no attribute %s" \
>>                      % (leader, "set_name") )
>>
>>
>> Of course this wouldn't use the object names directly... I guess I'll 
>> need to look in the C object code to see exactly how it works.  But 
>> the links you gave help.
> 
> 
> I guess you mean to indent the whole part after the first except and put 
> a try beforehand?

Yes,  I did.  I'm not sure why I left out the try.

      try:
          leader.__dict__["set_name"]("John")
      except:
          try:
              type(leader).__dict__["set_name"].__get__(leader, "John")
              # which results in...
              #    Person.set_name(leader, "John")
          except:
              raise( AttributeError,
                     "%s object has no attribute %s" \
                       % (leader, "set_name") )

> Apart from that you seem to be right - there can very well be values in 
> the class dict that don't follow the descriptor-protocol. However my 
> playing around with this stuff indicates that the creation of bound 
> methods relies on the method being wrapped in a descriptor - otherwise, 
> you get the notorious TypeError
 >
> set_name() takes exactly 1 argument (0 given)
> 
> as the binding doesn't occur.
> 
> Regards,
> 
> Diez

What I've noticed is you can block the visibility of a class attribute, 
which include methods, by inserting an object in the instance with the 
same name.

Python 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)] on 
win32
Type "help", "copyright", "credits" or "license" for more information.
 >>> class a(object):
...   def b(self, value):
...      print value
...
 >>> aa = a()
 >>> def foo(value):
...    print "%r" % value
...
 >>> aa.b('hello')
hello
 >>> aa.b = foo
 >>> aa.b('hello')
'hello'
 >>> del aa.b
 >>> aa.b('hi there')
hi there
 >>>

So the underlying mechanism for calling methods doesn't kick in until 
*after* an attempt to get an attribute of the same name in the instance.

 >>> a.boo = boo
 >>> def boo(self, value):
...    print list(value)
...
 >>> a.boo = boo
 >>> aa.boo('hello')
['h', 'e', 'l', 'l', 'o']

The attribute aa.boo is not there, so call boo.__get__() in class a.


Cheers,
Ron



More information about the Python-list mailing list