Home>

Decorator introduction:

Decorators are a high-level Python syntax. Decorators can process a function, method, or class.In Python, we have multiple methods for processing functions and classes.For example, in Python closures, we see function objects as the result of a function.Compared to other methods,Decorators have simple syntax,The code is highly readable.Therefore, decorators are widely used in python projects.

Decorators first appeared in Python 2.5. It was originally used to process callable objects such as functions and methods (such objects have __call__ methods). In Python 2.6 and later versions of Python, decorators were further used to process classes.

Decorators are mainly used to wrap functions,For some commonly used functions,For example:log printing,Function timing,Authentication.We can use decorators to achieve this,This can reduce the complexity of the entire program and reduce the amount of code in the program.

It's actually a function,the difference is,It takes a function as a parameter,It then returns an alternative function.

Let's look at a simple example:

def add_number (func):
def adder (arg):
return func (arg) +100
return adder
def f (x):
return x
f=add_number (f)
print f (20)

add_number is a decorator function,It accepts a function (f) as a parameter,Then return another function (adder) assigned to the original function,In this way, the original function implements the addition function without adding a new amount of code.

This is the original implementation of the decorator.

But, this method is still a bit inconvenient.After all, it ’s still around,Use f=add_number (f) to reassign the original function.

In fact, Python can use the following ways to simplify the reference to the decorator.

def add_number (func):
def adder (arg):
return func (arg) +100
return adder
@add_number
def f (x):
return x
print f (20)

Just a simple @add_numbe call, isn't it convenient,A lot easier,Basically did not break into the original code.

Um, everybody finds no,As a decorator,There are no more than two parameters each time:functions and function parameters,But the writing format is basically the same,Is there a way to simplify this writing?

Yes, Python provides a decorator package that can greatly simplify the writing of decorators.

so, the third implementation is:

from decorator import decorator
@decorator
def wrapper (func, arg):
return func (arg) +100
@wrapper
def f (x):
return x
print f (20)

Oh, it really is simpler ~

The above example accepts one parameter,In fact, the function itself can accept variable parameters.

Such as:

@decorator
def wrapper (f, arg1, * args, ** kwargs):
print "i am just a wrapper ~"
return f (arg1, * args, ** kwargs)
@wrapper
def f (arg1, * args, ** kwargs):
print arg1
for eachearg in args:
print "non-keyword arg:", eachearg
for eachkw in kwargs.keys ():
print "keyword arg:%s:%d"%(eachkw, kwargs [eachkw])
args=("joy", "steve")
kwargs={"age":20}
f ("china", * args, ** kwargs)

The output is:

i am just a wrapper ~
china
non-keyword arg:joy
non-keyword arg:steve
keyword arg:age:20

Regarding the differences between * args and ** kwargs, both can be used to represent variable-length parameters.It's just that the former is expressed by Yuanzu,No key value, the latter is a dictionary,There is a key value. Both can be used in the same function,However, * args must appear before ** kwargs.

For example:

def test_var_args_call (arg1, arg2, arg3):
print "arg1:", arg1
print "arg2:", arg2
print "arg3:", arg3
args=(1,2,3)
kwargs={"arg1":"1", "arg3":3, "arg2":"2"}
test_var_args_call (* args)
print "-----------------"
test_var_args_call (** kwargs)

Both achieve the same effect.

Finally, an example,Decorate a function by showing how long it took to execute

import time
def log (func):
def wrapper (* args, ** kw):
print "[%s]%s () was called ..."%(time.ctime (), func .__ name__)
return func (* args, ** kw)
return wrapper
@log
def foo ():
pass
for i in range (4):
foo ()
time.sleep (1)

The output is as follows:

[wed jul 27 09:17:23 2016] foo () was called ...
[wed jul 27 09:17:24 2016] foo () was called ...
[wed jul 27 09:17:25 2016] foo () was called ...
[wed jul 27 09:17:26 2016] foo () was called ...
  • Previous AngularJS model detailed introduction and example code
  • Next Questions about the many-to-many relationship table cannot be updated and inserted