Unification of Methods and Functions

David MacQuigg dmq at gain.com
Wed May 5 07:00:29 EDT 2004


On 4 May 2004 21:19:23 -0700, michele.simionato at poste.it (Michele
Simionato) wrote:

>Greg Chapman <glc at well.com> wrote in message news:<nvif90tkiv1i292600a18eqj18jd2to34a at 4ax.com>...
>> On Mon, 03 May 2004 11:44:06 -0700, David MacQuigg <dmq at gain.com> wrote:
>> 
>> >It seems to work in Michele Simionato's 'prototype' module.
>> >{ comp.lang.python, 4/28/04, "Prototypes in Python"}  It is global
>> >only to the called function, but the key requirement is met -- no
>> >alteration of the standard function calling sequence.
>> >
>> >Why can't it be a true global?
>> 
>> If I understand correctly, one drawback of his approach is that methods cannot
>> rebind globals.  A STORE_GLOBAL opcode will store its value into the globs
>> dictionary created when the method was fetched; this dictionary is not the same
>> as the module's dictionary, so the changed global will only be visible within
>> that method (and within that method call: the next time the method is fetched, a
>> new globs will be created).
>> 
>> ---
>> Greg Chapman
>
>I believe you are right (haven't checked yet) but I guess I can always
>change the globals from inside the method with something like
>
>currentmodule=sys.modules["__name__"]
>currentmodule.myglobal="something"
>
>Not that changing globals from a method is good style.

The one limitation I see in the prototype module is that I can't save
an unbound function and later call it with my choice of bind object.
A global __self__ might help in this situation.  e.g.

## This works:
bf = cat2.talk  # Save a bound function.
def func(bf):   # Pass it to another scope.
    bf()
func(bf)        # Call it.

## This does not:
uf = Cat.talk   # Save an unbound function.
uf() #=>
# AttributeError: type object 'Cat' has no attribute 'name'

I would like to be able to do something like:
__self__ = cat2
uf()

Maybe there is some other trick to get this to work.  It doesn't have
to be pretty.  This is a seldom-needed call, mostly for debugging.

>BTW, I do agree that my hack is an evil hack, the interesting thing 
>about it (for me) was the fact that inside the method I could use 
>"super.method(*args)" instead of the ugly
>"super(cls,self).method(*args)" syntax. I didn't think that was
>possible at all.

I don't care how evil the underlying machinery is.  It works nicely at
the user level.  This is something the prototype advocates have
missed.  They see metaclasses or descriptors and they freak.  If the
module had been written in C, they would not be complaining.

super.func() is cool.  I would not bother my students with
super(cls,self).func(), but the way super is used, it looks simple,
and it is simple.  I can have a hierarchy of classes, each one calling
a function from its parent, and without modifying anything but the
class headers, insert a new class in the middle of the hierarchy.

## New class:
class Feline(Animal):
...
    def show():
        super.show()
        print "Felines:", Feline.numFelines
...

>>> cat2.show()
Animals: 2
Felines: 2   <== Line added to previous output.
   Cats: 2

My interest in this "prototype" module is not the ability to clone
prototypes, but the simplification and unification of all function and
method calling styles.  If we leave out the cloning stuff, does it
make the implementation problems simpler?

-- Dave




More information about the Python-list mailing list