装饰器

装饰器

 

1、定义:假设我们要增强一个函数的功能,比如,在函数调用前后自动打印日志,但又不希望改变这个函数的源代码,这种在代码运行期间动态增加功能且又不改变源代码的方式,成为装饰器(Decorator)。本质上,decorator就是一个返回函数的高阶函数

2.实例

 如上图中的原函数为index(),我们通过装饰器为其增加了一个计算运行时间的功能,但是没有改变源代码,这就是为其增加了一个装饰器,装饰器的功能就是计时。

 关键点:@的语法,@timmer等同于进行了如下操作:index=timmer(index),函数名+()就是调用函数,一定要记住!!好多地方想不通原因就是在这里!

 思想就是把部内函数func()换成被装饰函数index()然后再运行闭包函数就好了(可能说的有点简单)

3、给认证装饰器增加一个登陆后再次调用是免认证的功能(字典,只在内存中能行)

import time

current_login = {'name': None, 'login': False}  # 建立一个字典,字典存储登录状态


def timmer(func):
    def wrapper():
        start_time = time.time()
        func()
        stop_time = time.time()
        print('run time is %s' % (stop_time - start_time))

    return wrapper


def auth2(auth_type='file'):
    def auth(func):
        def wrapper(*args, **kwargs):
            if current_login['name'] and current_login['login']:  # 判断状态是否被激活,若激活直接执行函数结束
                res = func(*args, **kwargs)
                return res
            if auth_type == 'file':
                name = input('username:')
                password = input('password:')
                if name == 'zhejiangF4' and password == 'sb945':
                    print('auth successful')
                    res = func(*args, **kwargs)
                    current_login['name'] = name  # 存储登录状态
                    current_login['login'] = True
                    return res
                else:
                    print('auth error')
            elif auth_type == "sql":
                print("haibuhui")

        return wrapper

    return auth


@timmer
@auth2(auth_type="file")
def index():
    print('welcome to index page')


@auth2("file")
def home():
    print("welcome to home page")


index()
home()  # 第一次执行index()函数是需要登录认证,但第二次执行home时就不需要再认证了

  

 4.帮助信息

import time

def timmer(func):

    def wrapper(*args,**kwargs):
        'ssssss'
        start_time=time.time()
        func(*args,**kwargs)   #home(name)
        stop_time=time.time()
        print('run time is %s' %(stop_time-start_time))
    return wrapper

@timmer
def func(x):
    'fun test'
    print(x)

func(1)
print(func.__doc__)    ###输出wrapper帮助信息
#print(help(func))


# import time
# from functools import wraps
# def timmer(func):
#     @wraps(func)
#     def wrapper(*args,**kwargs):
#         'ssssss'
#         start_time=time.time()
#         func(*args,**kwargs)   #home(name)
#         stop_time=time.time()
#         print('run time is %s' %(stop_time-start_time))
#     return wrapper
#
# @timmer
# def func(x):
#     'fun test'
#     print(x)
#
# func(1)
# print(func.__doc__)    ###输出wrapper帮助信息
# #print(help(func))

#输出func帮助信息

  

import time
from functools import wraps#从函数工具中调用wraps模块
def timmer(func):
    @wraps(func)#它就可以让你打印出的index.__doc__编程原函数的"dashabi"而不是wrapper函数的"000"
    def wrapper(*args,**kwargs):
        '000'
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print('run time is %s'%(stop_time-start_time))
        return res
    return wrapper
@timmer
def index():
    "dashabi"
    print("from index")
index()
print(index.__doc__)

  

 

 1 import time          #1
 2 def timmer(func):       #func的值是home的   #3
 3     def wrapper(name):       #4  #7                                 #闭包函数
 4         print(func)           #8
 5         start_time=time.time()      #9
 6         func(name)   #home(name)    #10
 7         stop_time=time.time()       #14
 8         print('run time is %s' %(stop_time-start_time))  #15
 9     return wrapper          #5
10 @timmer         #home=timmer(home)     #2    #6
11 def home(name):             #11
12     time.sleep(2)           #12
13     print('welcome to %s home page' %name)      #13
14 home('dragon')      #wrapper('dragon')
15 
16 
17 <function home at 0x0000000000D0E1E0>
18 welcome to dragon home page
19 run time is 2.0001142024993896

 

 

posted @ 2017-04-12 00:37  samyoung  阅读(187)  评论(0编辑  收藏  举报