Source era python Dry Share | python decorative magic of the early experience

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;

Guess you like

Origin blog.51cto.com/13007966/2449285