could ildg wrote: > I think decorator is a function which return a function, is this right? > e.g. The decorator below if from http://www.python.org/peps/pep-0318.html#id1. > > def accepts(*types): > def check_accepts(f): > assert len(types) == f.func_code.co_argcount > def new_f(*args, **kwds): > for (a, t) in zip(args, types): > assert isinstance(a, t), \ > "arg %r does not match %s" % (a,t) > return f(*args, **kwds) > new_f.func_name = f.func_name > return new_f > return check_accepts > > After I saw all the examples, I concluded that every decorator must > define an inner function which takes only one argument, the > function to decorate. Is this right?
It's close, but not quite right. (I will use the word "function" for the moment, but see below for why this is inaccurate.) Every *decorator* must take only one argument, the function to decorate. It is not at all necessary that a decorator define an inner function. Consider (from [1]): def onexit(f): import atexit atexit.register(f) return f onexit is a decorator because it takes a function and returns a function. In this case, it happens to be that the same function is accepted and returned. Note that in the 'accepts' example above, *check_accepts* is the decorator, not accepts. The accepts function is actually a function that *returns* decorators. Now about that word "function". Decorators are actually *callables* that accept a single *callable* and return a *callable*. Why does the terminology matter? Because I can construct decorators from classes too (from [2]): class memoized(object): def __init__(self, func): self.func = func self.cache = {} def __call__(self, *args): try: return self.cache[args] except KeyError: self.cache[args] = value = self.func(*args) return value except TypeError: return self.func(*args) Now the memoized decorator can be used just like any other decorator, e.g.: @memoized def fibonacci(n): if n in (0, 1): return n return fibonacci(n-1) + fibonacci(n-2) Note however that memoized is a *callable*, not a *function*. STeVe [1] http://www.python.org/peps/pep-0318.html [2] http://wiki.python.org/moin/PythonDecoratorLibrary -- http://mail.python.org/mailman/listinfo/python-list