Try it out: from functools import wraps def another_lower_level_decorator(func): @wraps( func ) def wrapped(*args, **kwargs): return func(*args, **kwargs) return wrapped def some_abstract_decorator(func): @wraps(func) @another_lower_level_decorator def wrapper(*args, **kwargs): # ... details omitted return func(*args, **kwargs) return wrapper @some_abstract_decorator def test(): """ This is a docstring that should be on the decorated function """ pass help(test) Prints: Help on function test in module __main__: test(*args, **kwargs) This is a docstring that should be on the decorated function As you can see it works! The docstring is there and the name assigned But this works just the same: def some_abstract_decorator(func): @another_lower_level_decorator @wraps(func) def wrapper(*args, **kwargs): # ... details omitted return func(*args, **kwargs) return wrapper wraps just fixes the docstrings/names. As long as all the decorators use wraps the order in which you apply it doesn't matter Btw, there is a much cooler decorator library : from decorator import decorator @decorator def another_decorator(func, *args, **kwargs): return func(*args, **kwargs) @decorator @another_decorator def some_abstract_decorator(func, *args, **kwargs): # ... details omitted return func(*args, **kwargs) @some_abstract_decorator def test(x): """ this is a docstring that should be on the decorated function """ pass.
Try it out: from functools import wraps def another_lower_level_decorator(func): @wraps( func ) def wrapped(*args, **kwargs): return func(*args, **kwargs) return wrapped def some_abstract_decorator(func): @wraps(func) @another_lower_level_decorator def wrapper(*args, **kwargs): # ... details omitted return func(*args, **kwargs) return wrapper @some_abstract_decorator def test(): """ This is a docstring that should be on the decorated function """ pass help(test) Prints: Help on function test in module __main__: test(*args, **kwargs) This is a docstring that should be on the decorated function As you can see it works! The docstring is there and the name assigned. But this works just the same: def some_abstract_decorator(func): @another_lower_level_decorator @wraps(func) def wrapper(*args, **kwargs): # ... details omitted return func(*args, **kwargs) return wrapper wraps just fixes the docstrings/names.As long as all the decorators use wraps, the order in which you apply it doesn't matter Btw, there is a much cooler decorator library: from decorator import decorator @decorator def another_decorator(func, *args, **kwargs): return func(*args, **kwargs) @decorator @another_decorator def some_abstract_decorator(func, *args, **kwargs): # ... details omitted return func(*args, **kwargs) @some_abstract_decorator def test(x): """ this is a docstring that should be on the decorated function """ pass.
Thanks. I think your first way it the correct way, after reading through this. I realized that if I use @wraps(func) after the inner decorator is applied, I'm assuming that the inner decorator also uses wraps(func).
By applying it to the decorated wrapper function I'm simply applying wraps functionality to my resulting function, thus making things more explicit (the low level decorator might be from a 3rd party, etc). – orokusaki Oct 6 '10 at 18:26.
That's right. The way this works is wrapper is defined. It calls func with its arguments.
Another_lower_level_decorator is called, with wrapper as its argument. The function it returns becomes the new value of wrapper. Wraps(func) is called to create a wrapper that will apply the name/docstring/etc.Of func to whatever function it's called on.
The return value of wraps(func), i.e. The produced wrapper function, is passed the current value of wrapper. This, remember, was the return value from another_lower_level_decorator.
Wraps(func)(wrapper) becomes the new value of wrapper. That value is returned by some_abstract_decorator, making that function suitable for use as a decorator. Or that's effectively it, anyway.
I think in practice wrapper is only reassigned to once.
Yes, that looks right to me. @another_lower_level_decorator will return a function, which @wraps will wrap so that it has the same name as func.
On Sun, 2004-08-15 at 08:22, Brett C. >>>I'll do a patch to fix the order and the corresponding tests. >>be bottom-up like the PEP.
> swamped this week, hence the delay getting time to do this). > correct fix (as well as also fixing the Lib/compiler package). In the middle of me doing all of this.
> it first appears. > test_eval_order() in test_decorators. > # they appear in the source.
> order you get with the current method (func = staticmethod(func)). Champion) to make the decision on the order. Listed, just the application order to be reversed.
With that for the rest of the week. And applying it if Guido okays the application order. Previous message: Python-Dev Re: Decorator order implemented backwards?
Next message: Python-Dev Decorator order implemented backwards?
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.