Why is class decorator on method loosing self?
George Sakkis
george.sakkis at gmail.com
Tue Nov 21 14:55:33 EST 2006
George Sakkis wrote:
> I don't think you can make it work without resorting to metaclass
> magic. At the point of decoration min_max is still a function, not a
> method, because class Foo has not been created yet. Here's a way to do
> it with a custom metaclass; whether you really want to do it is a
> different matter:
An improvement to my previous hack: leave memoize as is in the cookbook
(extending decoratorargs) and add two lines to decoratorargs:
# This would usually be defined elsewhere
class decoratorargs(object):
def __new__(typ, *attr_args, **attr_kwargs):
def decorator(orig_func):
self = object.__new__(typ)
self.__init__(orig_func, *attr_args, **attr_kwargs)
if callable(self):
self._customize = lambda cls: MethodType(self, None,
cls)
return self
return decorator
Now you don't need memoizefunction and memoizemethod, but you still
need the customized metaclass (changed __customize to _customize; name
turns to a PITA sooner or later):
class CustomizeMeta(type):
def __init__(cls, name, bases,dict):
for attr,val in dict.iteritems():
if hasattr(val, '_customize'):
setattr(cls, attr, val._customize(cls))
#==== examples =============================================
@memoize(3)
def fib(n):
return (n > 1) and (fib(n - 1) + fib(n - 2)) or 1
class Foo(object):
__metaclass__ = CustomizeMeta
def __init__(self, i): self._i = i
def banner(self):
print "Testing method"
@memoize(3)
def min_max(self, sequence):
self.banner()
return min(sequence), max(sequence)
foo = Foo()
print foo.min_max([9,7,5,3,1])
George
More information about the Python-list
mailing list