On Mar 4, 5:27 am, Bruno Desthuilliers <bruno. [EMAIL PROTECTED]> wrote: > ?? a écrit : > > > Howdy everyone, > > > This is a big problem puzzles me for a long time. The core question is: > > How to dynamically create methods on a class or an instance? > > class Foo(object): > pass > > def bar(self, arg): > print "in bar : self == % - arg == %s" % (self, str(arg)) > > def baaz(self, arg): > print "in baaz : self == % - arg == %s" % (self, str(arg)) > > f = Foo() > > # adding bar as a method to class Foo > Foo.bar = bar > > # f now can use bar: > f.bar(42) > > # as well as new instances of Foo, of course > g = Foo() > g.bar() > > # adding baaz as a method to f, the old way: > import new > f.baaz = new.instancemethod(baaz, f, type(f)) > > f.baaz() > > # adding baaz as a method to g, the other way: > g.baaz = baaz.__get__(g, type(g)) > > g.baaz() > > > Let me state it step by step. > > 1. > > def gunc(self): > > pass > > class A(object): > > def func(self): > > pass > > a = A() > > a.func # gives "bound method", type is "instancemethod" > > A.func # gives "unbound method", type is "instancemethod" > > gunc # gives "function", type if "function" > > > # ?? Does this line attach a method to instance? ... I don't think so. > > a.gunc = gunc > > It doesn't. > > > I found stardard library 'new' may help. Is that right? > > cf above. If you work with old-style classes, you'll need > new.instancemethod. > > > 2. > > a = A() # instance of old class A > > # Do attach a new method to class A... > > b = A() # instance of new class A > > Does "a" can get the new method automatically? > > Yes. In Python, a class is itself an object, and is an attribute of it's > instances (instance.__class__). Names are resolved at runtime, and > attributes not found in the instance's __dict__ are looked up in the > class (and then in the superclasses etc). > > > Does new method have the *same* concept level with old methods? > > The newly added method works exactly the same way as already existing > ones. Not a single difference. The class statement is just syntactic > sugar anyway. The following snippets are equivalent: > > # sugar-coated: > class Boo(object): > faaz = 0 > > def far(self): > type(self).faaz += 1 > print self > > def frob(self): > print "yadda" > > # raw: > def far(self): > type(self).faaz += 1 > print self > > Boo = type('Boo', (object,), dict(faaz=0, far=far)) > > def frob(self): > print "yadda" > > Boo.frob = frob > > > Especially, if there > > are classes inherit from class A, how does name resolution work on this > > case? > > As usual. > > > 3. > > How do I write a decroator for a method? > > Mostly the same way you'd write a decorator for a function > > > Eg: > > class A(object): > > @my_dec > > def func(self): > > pass > > Here, my_dec should return a method rathar than a function/lambda. Am I > > right? > > Nope. Functions defined within a class statement are plain ordinary > functions. It's the lookup mechanism that "turns them into methods" when > they are looked up as attribute of a class. In fact, Python "methods" > are thin callable wrappers around a function, a class and (most of the > time) an instance, wrappers which are created - usually at lookup time - > by the __get__ method of the function type (you may want to read about > the descriptor protocol on python.org - in the section about new style > classes IIRC). > > Anyway, you can explore this by yourself: > > >>> Boo.far > <unbound method Boo.far> > >>> b.far > <bound method Boo.far of <__main__.Boo object at 0xb787f96c>> > >>> Boo.__dict__['far'] > <function far at 0xb7c28aac> > >>> Boo.__dict__['far'] is far > True > >>> f1 = b.far > >>> f2 = b.far > >>> f1 is f2 > False > >>> f1() > <__main__.Boo object at 0xb787f96c> > >>> f2() > <__main__.Boo object at 0xb787f96c> > >>> dir(f1) > ['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', > '__get__', '__getattribute__', '__hash__', '__init__', '__new__', > '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', > 'im_class', 'im_func', 'im_self'] > >>> f1.im_class > <class '__main__.Boo'> > >>> f1.im_func > <function far at 0xb7c28aac> > >>> f1.im_func is far > True > >>> f1.im_self > <__main__.Boo object at 0xb787f96c> > >>> f1.im_self is b > True > >>> bf = Boo.far > >>> bf.im_func > <function far at 0xb7c28aac> > >>> bf.im_func is far > True > >>> bf.im_class > <class '__main__.Boo'> > >>> bf.im_self > >>> bf.im_self is None > True > >>> far.__get__(b, Boo) > <bound method Boo.far of <__main__.Boo object at 0xb787f96c>> > >>> far.__get__(b, Boo).im_func is far > True > >>> > > So, to answer your question: what you are decorating are functions, not > methods.
Can you overload -type-'s decision of what to 'bind'?... whenever it is it makes it. -- http://mail.python.org/mailman/listinfo/python-list