On Sat, 7 May 2005 01:06:31 +0200, "Fredrik Lundh" <[EMAIL PROTECTED]> wrote:
>James Stroud wrote: > >> I did this: >> >> py> class bob(object): >> ... def __init__(self,**kwargs): >> ... for fname,func in kwargs.items(): >> ... setattr(self, fname, lambda *args : func(*args)) >> ... >> py> def doit(): >> ... print "wuzzup?" >> ... >> py> abob = bob(doit=doit) >> py> >> py> abob.doit() >> wuzzup? >> >> Much to my surprise, this works fine. > >why is that surprising? "doit" is a callable, you wrap it in another >callable, and then you store it in an attribute. > >that's no different from storing a integer as an attribute, and it >sure doesn't turn your callable into an instance method. > >> 1. What exactly is going on? > >see above. > >> 2. How can I get ref to self passed to doit() if I want it to? > >try using this bob instead: > > import new > > class bob(object): > def __init__(self, **kwargs): > for fname, func in kwargs.items(): > setattr(self, fname, new.instancemethod(func, self, bob)) > ISTM "instancemethod" doesn't really tell the story of what that usage means, which is actually storing a bound method as an attribute of the instance it _happens_ to be bound to. I.e., this "instancemethod" is a bound method that could be stored as an attribute of _anything_ and if used as a callable the function would see the same bound "self" no matter where the bound method was picked up from (well, unless someone perversely interfered with some hack ;-) I am wondering whether anyone mistakenly thinks that there is a dynamic binding process involved at the time of the attribute access for the instancemethod, as there is for an ordinary method. Of course I know you know how to mess with the class to make function attributes of instances get dynamically bound as if they were class attributes accessed via the instance, but I wonder if others appreciate this distinction, or would be surprised by e.g., >>> import new >>> >>> class bob(object): ... def __init__(self, **kwargs): ... for fname, func in kwargs.items(): ... setattr(self, fname, new.instancemethod(func, self, bob)) ... >>> def m(self, *args): ... return self, args ... >>> b = bob(bm=m) >>> vars(b) {'bm': <bound method bob.m of <__main__.bob object at 0x02EF16EC>>} >>> b.bm('hi') (<__main__.bob object at 0x02EF16EC>, ('hi',)) >>> bmg = b.bm >>> bmg('hello') (<__main__.bob object at 0x02EF16EC>, ('hello',)) >>> class C: pass ... >>> c=C() >>> c.m = b.bm >>> c.m('greets') (<__main__.bob object at 0x02EF16EC>, ('greets',)) >>> C.M = b.bm >>> C.M('saludos') (<__main__.bob object at 0x02EF16EC>, ('saludos',)) >>> c.M('amigos') (<__main__.bob object at 0x02EF16EC>, ('amigos',)) Obviously "self" has nothing to do with c or C etc. Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list