Why we will use obj$func() often

Mike C. Fletcher mcfletch at rogers.com
Thu Apr 22 16:21:59 EDT 2004


Mark Hahn wrote:

>My apologies.  I posted this to c.l.p. by accident.   I meant to post this
>to Prothon-users.
>  
>
Oh, no problem, there's some Python content (see below for some comments 
on it)...
...

>># Python
>>
>>class klass:
>>    def __init__(self):
>>        self.me = 1
>>    def func(self):
>>        print "func1,self"+str(self.me),
>>
>>class klass2(klass):
>>    def __init__(self):
>>        self.me = 2
>>    def func(self):
>>        klass.func(self)        # delegation
>>        print "func2,self"+str(self.me),
>>
>>inst = klass2()
>>inst.func()    # prints  func1,self2   func2,self2
>>
>>    
>>
...

>>In Python the call klass.func() was different because Python knows that
>>klass is a class and therefore obviously cannot be the target of call (an
>>instance), so it made the programmer pass the instance self to use as a
>>parameter.
>>    
>>
This isn't really a very clear description of what's going on in 
Python.  It won't matter to the Prothon users, but don't want any Python 
users to get confused...

    Looking up klass.func returns an unbound instance method, this is a
    function wrapper which basically just says "hey, you're a member
    function of a class, check to be sure that your first argument is a
    member of that class".  This is done by the function's descriptor
    hooks which allow it to return a wrapped object when the user
    attempts to retrieve the value from another object (such as a class
    or an instance).  So, in a sense, yes, the class cannot be the
    target of that *particular* call, as the unbound method object you
    retrieved will reject anything other than an instance of the class.

    Bound instance methods are a similar wrapper, but they say
    "curry/bind your first argument (normally self) to this value then
    call the underlying function".  They are created on object.method
    access by the same function descriptor hooks.

The point of all that being that classes most definitely *can* be the 
target of a call.  Python's classes are first-class objects.  In 
particular, they are instances of metaclasses, and can have meta-methods 
defined which take the class as their first parameter just like a normal 
method-call.

 >>> class k(type):
...     def r( cls ):
...         return 42
...    
 >>> class x:
...     __metaclass__ = k
...    
 >>> x.r()
42
 >>>

There's very little "special" about classes other than that they have 
some syntactic shortcuts for creating them and for looking up attributes 
of their instances within them.  Python isn't looking at every method 
call and saying "hey, that's a class, that can't be the first parameter 
to a function/method!", it (particularly the unbound instance object) is 
saying "hey, you're not an instance of my class, go to heck" and never 
thinks about whether the object is *particularly* a class or not.

Classes are special in Python, but not nearly as special as you might 
think from a class-less perspective :) ,
Mike

    By the way, the modern Python idiom is:

        super( klass2, self ).func( )

    but that wouldn't help in explaining the logic for the Prothon
    choice, so no biggie :) .

_______________________________________
  Mike C. Fletcher
  Designer, VR Plumber, Coder
  http://members.rogers.com/mcfletch/






More information about the Python-list mailing list