The application scenario of the adorner, the more classic have insert log, performance test, transaction processing and so on. on the code:
def foo (): print (' foo ')
This code, if we want to add new features without changing the original functionality, you can do this:
def foo (): print (' foo ') def wrapper (func): def inner (): print (' before ') func () print (' after ') return Innerfoo=wrapper (foo) foo ()
Printing results:
Before
Foo
After
Python provides a syntactic sugar to reduce the amount of character input.
def wrapper (func): def inner (): print (' before ') func () print (' after ') return Inner@wrapper #wrapper =wrapper (foo) def foo (): print (' foo ') foo ()
Printing results:
Before
Foo
After
Let's take a look at @wrapper's notation, adding this line to the Foo function definition is exactly equivalent to the other write Foo = wrapper (foo), with no additional mana.
In addition to the less character input, there is an additional benefit: it looks more like a decorator. This is not enough to meet our needs, we want to give the Foo function parameters, how to deal with it?
On the code:
def wrapper (func): def Inner (sth): print (' before ') func (sth) print (' after ') return Inner@wrapper #wrapper =wrapper (foo) def foo (sth): print (STH) foo (' Apple ')
Printing results:
Before
Apple
After
This is the case of passing a parameter, if we want to pass a lot of parameters, in addition to multiple positional parameters, but also want to pass the keyword parameters, this time what to do? the func function can be perfectly implemented by *args,**kwargs receiving arguments!
def wrapper (func): def Inner (*args,**kwargs): print (' before ') func (*args,**kwargs) print (' after ' ) return inner@wrapper #wrapper =wrapper (foo) def foo (sth1,sth2,sth3,sth4): print (STH1,STH2,STH3,STH4) Foo (' Apple ', ' orange ', ' banana ', ' lemon ')
Printing results:
Before
Apple Orange Banana lemon
After
Further, our Foo function sometimes needs to use the return value, and then how to handle it?
Import Timedef Wrapper (func): def Inner (*args,**kwargs): print (' before ') ret = func (*args,**kwargs) print (' after ') print (ret) return ret return inner@wrapper #foo =wrapper (foo) def foo (ARG): Print (ARG) return 111res=foo (' Apple ') time.sleep (1) printing (res) results: beforeappleafter111111 (printed in 1 seconds)
In addition, the Functools module is provided with an adorner:wraps (wrapped,assigned,updated).
function is a few special properties such as the function name, after being decorated, the function name Foo in the above example becomes the name of the wrapper function inner, we can see the following example:
def wrapper (func): def inner (*args, **kwargs): print ("Before ...") ret = func (*args, **kwargs) Print ("after/...") return ret return inner@wrapper # foo = wrapper (foo)-->innerdef foo (STH): print (STH) return "AAA" prints (foo.__name__) Results: Inner
At this time wraps embodies its role: it can retain the special properties of the decorated function.
Import Functoolsdef Wrapper (func): @functools. Wraps (func) def inner (*args, **kwargs): print ("Before ... ") ret = func (*args, **kwargs) print (" after/... ") return ret return inner@wrapper # foo = Wrapper (foo)-->innerdef foo (sth): printed (STH) return "AAA" Print (foo.__name__) results: foo
Some interesting little exercises can be done about decorators.
One: Write functions, (function execution time is random) Two: write the adorner, for the function plus statistical time function Three: write the adorner, for the function plus the function of authentication four: to write a decorator, for a number of functions plus authentication function (user's account password from the file), required to log on successfully, Subsequent functions do not need to enter the user name and password Note: Read the dictionary from the file as a string, you can use the eval (' {' name ': ' Egon ', ' Password ': ' 123 '} ') into the dictionary format five: Write a function to download the content of the Web page, The requirement function is: The user passes in a URL, the function returns the download page The result six: writes the adorner for the topic five, realizes the function which caches the webpage content: concretely: Implements the download the page to store in the file, if the file has the value (the file size is not 0), will prefer to read the webpage content from the file, otherwise, And then save it to the file. Seven: Remember that we use the concept of function objects, to make a function dictionary operation, come, we have a larger approach, the file at the beginning of the declaration of an empty dictionary, and then before each function with an adorner, complete the automatic addition to the dictionary operation
python--Decorator