En Tue, 04 Mar 2008 16:45:40 -0200, <[EMAIL PROTECTED]> escribió: >> > 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. > >>>> from types import FunctionType, MethodType >>>> class A( FunctionType ): pass > ... > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > TypeError: type 'function' is not an acceptable base type
Use delegation instead of inheritance. This class is almost indistinguishable from a true function (when used as a method): py> class myfunction(object): ... __slots__ = ('func',) ... # ... def __init__(self, func): ... object.__setattr__(self, 'func', func) ... # ... def __get__(self, instance, owner): ... print "__get__ called for",instance ... return self.func.__get__(instance, owner) ... # ... def __getattr__(self, name): ... return getattr(self.func, name) ... # ... def __setattr__(self, name, value): ... object.__setattr__(self.func, name, value) ... py> py> class P(object): ... def foo(self, x): print 'foo',x ... # ... @myfunction ... def bar(self, x): print 'bar',x ... py> p = P() py> p.foo(1) foo 1 py> p.bar(2) __get__ called for <__main__.P object at 0x00A3D650> bar 2 py> P.foo(p, 1) foo 1 py> P.bar(p, 2) __get__ called for None bar 2 py> print "p.foo", p.foo, type(p.foo) p.foo <bound method P.foo of <__main__.P object at 0x00A3D650>> <type 'instancem ethod'> py> print "p.bar", p.bar, type(p.bar) p.bar __get__ called for <__main__.P object at 0x00A3D650> <bound method P.bar of <__main__.P object at 0x00A3D650>> __get__ called for <__ main__.P object at 0x00A3D650> <type 'instancemethod'> py> print set(dir(p.foo))==set(dir(p.bar)) __get__ called for <__main__.P object at 0x00A3D650> True py> print "P.foo", P.foo, type(P.foo) P.foo <unbound method P.foo> <type 'instancemethod'> py> print "P.bar", P.bar, type(P.bar) P.bar __get__ called for None <unbound method P.bar> __get__ called for None <type 'instancemethod'> py> print set(dir(P.foo))==set(dir(P.bar)) __get__ called for None True py> P.__dict__['foo'] <function foo at 0x00A3BCB0> py> P.__dict__['bar'] <__main__.myfunction object at 0x00A3D690> Ok, let's try returning a different thing from __get__: bound method -> partial with self already bound; unbound method -> the original function. py> from functools import partial py> py> class myfunction2(myfunction): ... def __get__(self, instance, owner): ... if instance is None: ... return self.func ... return partial(self.func, instance) ... py> @myfunction2 ... def baz(self, x): print 'baz',x ... py> P.baz = baz py> print p.baz <functools.partial object at 0x00A3E5A0> py> print P.baz <function baz at 0x00AB1030> py> p.baz(3) baz 3 py> P.baz(p,3) baz 3 -- Gabriel Genellina -- http://mail.python.org/mailman/listinfo/python-list