Python Decorators (ii): Decorator parameter __python

Source: Internet
Author: User

Python decorators ii:decorator Arguments

October, 2008

(This is the second part of the chapter excerpt from the Python 3 Patterns & Idioms (Python3 mode and usage), click here to read the first part)

review: Non-parameter-free Decorators

In the previous article, I described how to use decorators without parameters and use a class to implement it. Because I find it easier to accept.

If a parameterless decorator is created, the decorated function is passed to the constructor, and the __call__ () method is invoked each time the decorated function is invoked:

Class Decoratorwithoutarguments (object):

def __init__ (self, f):

"""

If There are no decorator arguments, the function

To being decorated is passed to the constructor.

"""

Print "Inside __init__ ()"

SELF.F = f

def __call__ (self, *args):

"""

The __call__ method isn't called until the

Decorated function is called.

"""

Print "Inside __call__ ()"

SELF.F (*args)

Print "After Self.f (*args)"

@decoratorWithoutArguments

Def sayhello (A1, A2, A3, A4):

print ' SayHello arguments: ', A1, A2, A3, A4

print "After decoration"

Print "Preparing to call SayHello ()"

SayHello ("Say", "hello", "argument", "list")

Print "After the SayHello () call"

SayHello ("A", "different", "set of", "arguments")

Print "after second SayHello ()"

All parameters of the decorated function are passed to __call__ (). The output results are:

Inside __init__ ()

After decoration

Preparing to call SayHello ()

Inside __call__ ()

SayHello Arguments:say Hello argument list

After Self.f (*args)

After the SayHello () call

Inside __call__ ()

SayHello arguments:a different set of arguments

After Self.f (*args)

After second SayHello ()

Note that __init__ () is the only method that is called to execute decoration, and __call__ () is invoked each time the SayHello () of the decorated is invoked.

containing parameters. Decorators

Now let's modify the code above to see what the result is when you add the parameters to the decorator.

Class Decoratorwitharguments (object):

def __init__ (self, arg1, arg2, ARG3):

"""

If There are decorator arguments, the function

To was decorated is isn't passed to the constructor!

"""

Print "Inside __init__ ()"

SELF.ARG1 = Arg1

SELF.ARG2 = arg2

SELF.ARG3 = Arg3

def __call__ (self, f):

"""

If There are decorator arguments, __call__ () is only called

Once, as part of the decoration process! can only give

It a single argument and which is the function object.

"""

Print "Inside __call__ ()"

def wrapped_f (*args):

Print "Inside wrapped_f ()"

Print "Decorator arguments:", Self.arg1, Self.arg2, SELF.ARG3

F (*args)

Print "After F (*args)"

Return Wrapped_f

@decoratorWithArguments ("Hello", "World", 42)

Def sayhello (A1, A2, A3, A4):

print ' SayHello arguments: ', A1, A2, A3, A4

print "After decoration"

Print "Preparing to call SayHello ()"

SayHello ("Say", "hello", "argument", "list")

Print "After the SayHello () call"

SayHello ("A", "different", "set of", "arguments")

Print "after second SayHello ()"

As you can see from the output, adding parameters causes a great change in program execution.

Inside __init__ ()

Inside __call__ ()

After decoration

Preparing to call SayHello ()

Inside Wrapped_f ()

Decorator Arguments:hello World 42

SayHello Arguments:say Hello argument list

After F (*args)

After the SayHello () call

Inside Wrapped_f ()

Decorator Arguments:hello World 42

SayHello arguments:a different set of arguments

After F (*args)

After second SayHello ()

Now the decoration method calls the constructor, and then immediately calls __call__ (), which can only contain one parameter (the function object) and return the decorated function object that replaces the original function. Note that __call__ () is invoked only once during the current decoration period, and the decorated function returned from __call__ () can then be used in the actual call.

Although this mechanism has some rationality-the constructor can get the decorator parameter here, but the __call__ () object can no longer be used as the decorated function. So you have to use __call__ () to perform decoration-you might be surprised to see this in a very different way for the first time, not to mention that you have to write and decorator complete different code.

containing Decorator parameters of Decorator function

Finally, let's look at a more complex decorator function implementation that requires you to handle all the details:

def decoratorfunctionwitharguments (Arg1, Arg2, ARG3):

Def wrap (f):

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.