Steven Bethard: Thank you so much! Your answer is very very helpful~
On 5/19/05, Steven Bethard <[EMAIL PROTECTED]> wrote: > 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 > -- http://mail.python.org/mailman/listinfo/python-list