Simple decorator
1.1.1. One of the most simple décor behavior
One feature decorator is: On the basis of the implementation of the original function, increase content.
Let's give a simple example:
we can use it as a journal printer unit, before executing the function, I will politely inform you about
"Honey coder, I want to perform the"
After the execution, will inform you coder.
Is not it interesting?
So, how we execute the original function that?
✔ the name of the original function to the decorative function, decorative function will have the ability to perform old functions.
Old function, the function to be decorated
def fun():
print('我是老函数')
def factory(old_fun):
print('='*20)
old_fun()
print('='*20)
factory(fun)
1.1.2. Perfect decoration behavior
❓ above decorative behavior as well as what issues?
◇ need to call the original function by decorative plants, calling the original function of this business sector, the large area to modify the code;
❓ So how do you improve that this problem?
How to design a way, without changing the original name of the function, also performs decorative plant that when you call.
◇ old_name = factory (old_name)
def fun():
print("我是fun")
def factory(a):
def tmp():
print("="*10)
a()
print("="*10)
return tmp
fun = factory(fun)
fun()
1.1.3.python decorator syntax sugar
old_name = factory (old_name) This sentence is to generate a core statement decorator. To avoid always write such code is no brain, python provides a convenient wording, we call syntax sugar.
Syntactic sugar wording:
· find the function to be decorated
· @ write on it, and then with the name of the decorator function br /> @ decortate
DEF Fun ():
Print ( 'in Fun () ...')
1.1.4 summary
python decorators written ideas:
1. define a mediation function, which is named decorate behavior, receiving a callable
def get_timer (fn):
Pass
2. realize decorative function behavior inside the intermediary function
def get_timer (fn) :
DEF wrapper ():
... ... # code for decoration
3. Finally, return decoration behavior in the mediation function function name:
DEF get_timer (the Fn):
DEF wrapper ():
... ... # code for decoration
wrapper return br /> [Note]: returns the function name, rather than function calls
4. before the function that needs to be decorated, the definition of @ decorator name
@get_timer
DEF Fun ():
Pass
Several forms 1.2.python decorator
1.2.1 No parameters decorator.
Demo1: increase the function when the function is running:
import time
def time_fun(func):
def my_time():
print(f"{func.__name__} running at {time.ctime()}")
func()
return my_time
@time_fun
def fun1():
print("+++++++++")
fun1()
time.sleep(2)
fun1()
1.2.2. There are decorative function parameters
The core is the behavior of the interior decorator function has been renamed;
form internal functions to meet the original functional form;
import time
def time_fun(func):
def my_time(arg1): # 内部函数里预留接口
print(f"{func.__name__} running at {time.ctime()}")
func(arg1) # 原函数传递参数
return my_time
@time_fun
def fun1(arg1):
print("+++++{}++++".format(arg1))
fun1(10)
time.sleep(2)
fun1(10)
1.2.3. Decorative function has been uncertain parameters and return values
Original function returning, interior function also receives the return value is returned.
import time
def time_fun(func):
def my_time(*args, **kwargs):
print(f"{func.__name__} running at {time.ctime()}")
func(*args, **kwargs)
return my_time
@time_fun
def fun1(arg1, arg2, name):
print("+++++{},{},{}++++".format(arg1, arg2, name))
fun1(10, 20, name='rocky')
time.sleep(2)
fun1(10, 20, name='jim')
1.2.4 Changing the behavior of decorator (pass parameters to the decorator)
In decorators, we also have a need, depending on the parameters passed, decorative behavior will be different, then how to define this decorator that.
First then understand the syntax decorators:
@time_fun
def fun1(arg1, arg2, name):
print("+++++{},{},{}++++".format(arg1, arg2, name))
原材料名称= 装饰器名称(原材料名称)
@time_fun(“itsource”)
def fun1(arg1, arg2, name):
print("+++++{},{},{}++++".format(arg1, arg2, name))
fun1 = time_fun(“itsource”)(fun1)
This point of view, we must ensure that time_fun ( "itsource") returned content happens to be a standard to meet the decorator.
import time
def time_fun(flags):
def time_arg(func):
def my_time(*args, **kwargs):
print(f"{func.__name__} running at {time.ctime()}")
print("the flags is {}".format(flags))
return func(*args, **kwargs)
return my_time
return time_arg
@time_fun("itsource")
def fun1(arg1, arg2, name):
print("+++++{},{},{}++++".format(arg1, arg2, name))
fun1(10, 20, name='rocky')
time.sleep(2)
fun1(10, 20, name='jim')
1.2.5. Decorator with a defined class (Learn)
What ❓ executable object exactly?
✔ having call object space method, it is called an executable objects, each defining a function, defined in the equivalent space call method.
How ❓ use classes to implement the decorator
@Test # = Test Fun (Fun)
DEF fun ():
Pass
Test the init method should receive the name of the function is decorative
call fun () is actually called Test class call the method
class the Test ():
DEF the init (Self, Fn):
self.old_fun = Fn
def __call__(self,):
... ... # 装饰内容
ret = self.old_fun()
@Test
def fun(a, b, name):
pass
fun()
1.3 multilayer decorative
In the actual development, a primary function, can use more decorative function modified, such behavior is called multilayer decorative.
For multilayer decorative, to understand his execution.
def bold(fn):
def wrapper():
return f'<b>{fn()}</b>'
return wrapper
def italic(fn):
def wrapper():
return f'<i>{fn()}</i>'
return wrapper
@italic
@bold
def hello():
return 'Hello World'
print(hello())
[Results]:
<I> <B> the Hello World </ B> </ I>
. 1.4 summarizes
l decorator actually is a function (callable);
l receiving a name and old function;
l returns the name of the new function ;
l call the old functions in the new function;