It is a crying shame that this article fails to realize that decorator.decorator is itself a decorator, and that failing to use it as such undermines the premise that decorators are "a neat way to modify functions". With this realization:<p><pre><code> @decorator.decorator
def heading1(func, *args, **kwargs):
return "<h1>" + func(*args, **kwargs) + "</h1>"
</code></pre>
With this construction, you no longer need to have the two copies of the function: the degenerate wrapper can be removed and replaced with this decorator.<p>Even if the library didn't provide this, you can just look at this code and feel "no, wait, this is wrong: this should be implemented with a decorator" and write this:<p><pre><code> def better_decorator(function):
def wrapped(function, *args, **kw):
return decorator.decorator(function, *args, **kw)
return decorator.decorator(wrapped, function)
</code></pre>
This new decorator, @better_decorator, can now be used in place of @decorator.decorate in the above example, and again solves the problem of the degenerate wrapper by generalizing it into a single universal degenerate wrapper.