Python Forum

Full Version: decorators within decorators
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I am trying to build decorators within decorators.
I thought I take the example I have discussed previously.
I have a function that multiplies x and y.
My decorator function just prints out a statement saying "x*y = "
I have now added a superdecorator function around my decorator function where I now want to multiply (n*x)*(n*y) i.e. if n=2 then I want to multiply the double of x and the double of y.
Here is my code below but I am getting an error message

print('{} * {} = '.format(*args*n,**kwargs*n), end='')
TypeError: unsupported operand type(s) for *: 'dict' and
def superdecorator(n):
    def decorator(func):
        def wrapped(*args, **kwargs):
            print('{} * {} = '.format(*args*n,**kwargs*n), end='')
            return func(*args*n, **kwargs*n)
        return wrapped
    return decorator
 
 
@superdecorator(2)
def mult(x,y):
    return x*y
Thank for share this
กำถั่ว
Why don't you implement that check in the first decorator?
ok, I just take it as no one on here really knows how to do this.
Just wrap the the first decorator into a wrapper function and return it.

def superdecorator(decorator):
    def wrapper(*args, **kwargs):
        def decorator(func):
            def wrapped(*args, **kwargs):
                print('{} * {} = '.format(*args*n,**kwargs*n), end='')
                return func(*args*n, **kwargs*n)
            return wrapped
        return decorator
    return wrapper
But you will have a problem with the function names.
Actually this happens with the first decorator too. If you have any docstrings in the decorated function you will lose it. See functools.wraps
Some point,decorators within decorators with several argument is confusing for most.
I know well how it works,but can really struggle if i haven't look it at for a while.
(Mar-28-2018, 05:28 PM)wavic Wrote: [ -> ]If you have any docstrings in the decorated function you will lose it. See functools.wraps
Yes this is important,also wrapt take this further.
Graham Dumpleton Wrote:The wrapt module focuses very much on correctness.
It therefore goes way beyond existing mechanisms such as functools.wraps() to ensure that decorators preserve introspectability,
signatures, type checking abilities etc.
So if i should done anything serious with decorator today i would look into using wrapt
Graham Dumpleton author of wrapt: Hear no evil, see no evil.

David Beazley Decorators with Arguments.

Decorators can be useful,two of my favorite Python packages use decorator Flask and Click .
I used Click in my tutorial here
So the user interface get clean by hiding all code that's not needed to be shown,
like cheeking for path with type=click.Path(exists=True).
This also mean that i don't have to write error checking for Path in my code.
@click.command() 
@click.argument('file', type=click.Path(exists=True), metavar='<file>')
def play(file):
   ....
Ok,sir Good Explain Thank you again.royal1688