装饰器(十五)

import time

def timer(func):
    def swapper(*args,**kargs):
        start_time = time.time()
        res = func(*args,**kargs)
        end_time = time.time()
        print(end_time-start_time)
    return swappe

装饰器:本质就是函数,用来给其他函数增加 附加功能

原则:

1.不修改被修饰函数的源代码

2.不修改被修饰函数的调用方式

装饰器 = 高阶函数 +  函数嵌套 +闭包

 

高阶函数:

  1.函数的参数是一个函数名

  2.函数的返回值是一个函数名

  3.满足以上两个条件中的一个就是高阶函数

import time

def foo():
    time.sleep(2)

def test_swapper(func):
    time_start = time.time()
    func()
    time_end = time.time()
    print('函数执行时间:%s' %(time_end - time_start))

test_swapper(foo)  # 修改了函数的调用方式 foo()

'''
函数执行时间:2.0000498294830322
'''
import time

def foo():
    time.sleep(2)
    print('from foo...')

def test_swapper(func):
    time_start = time.time()
    func()
    time_end = time.time()
    print('函数执行时间:%s' %(time_end - time_start))
    return func

foo = test_swapper(foo)
foo()
'''
from foo...
函数执行时间:2.0009238719940186
from foo... # 多执行了一次
'''

以上说明高阶函数一个人满足不了装饰器的条件

 

函数嵌套和函数闭包

内部函数对外部函数作用域里变量的引用(非全局变量),则称内部函数为闭包

闭包似有化了变量,原来需要类对象完成的工作,闭包也可以完成

闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存

# 嵌套和闭包
def father(name):
    def son():
        print('father is %s' % name)
        def grandson():
            print('grandfather is %s' %name)
        grandson()
    son()
    print(locals())
father('world')
'''
father is world
grandfather is world
{'son': <function father.<locals>.son at 0x000002287CA55C80>, 'name': 'world'}

'''

 

高阶函数 +  函数嵌套 +闭包

# 框架
def timer(func):
    def wapper():
        pass
    return wapper()

 

 

import time

def foo():
    time.sleep(2)
    print('from foo...')

def test_swapper(func):
    def son():
        time_start = time.time()
        func()
        time_end = time.time()
        print('函数执行时间:%s' %(time_end - time_start))
    return son

foo = test_swapper(foo)
#@timer 就相当于 foo = timer(foo)
foo() ''' from foo... 函数执行时间:2.0008609294891357 '''

#@timer 就相当于 foo = timer(foo),故可以如下写,就是装饰器的简单实现

import time

# # 框架
# def timer(func):
#     def wapper():
#         pass
#     return wapper()

def timer(func):
    def swapper():
        time_start = time.time()
        func()
        time_end = time.time()
        print('函数执行时间:%s' %(time_end - time_start))
    return swapper

@timer
def foo():
    time.sleep(2)
    print('from foo...')

#foo = timer(foo)     # @timer 就相当于 foo = timer(foo)
foo()

 

加返回值

import time

# # 框架
# def timer(func):
#     def wapper():
#         pass
#     return wapper()

def timer(func):
    def swapper():
        time_start = time.time()
        res = func()
        time_end = time.time()
        print('函数执行时间:%s' %(time_end - time_start))
        return res
    return swapper

@timer
def foo():
    time.sleep(2)
    print('from foo...')
    return 123

#foo = timer(foo)     # @timer 就相当于 foo = timer(foo)
res = foo()
print(res)
'''
from foo...
函数执行时间:2.0008599758148193
123
'''

 

加参数:

 

import time

def timer(func):
    def swapper(*args,**kargs):
        start_time = time.time()
        res = func(*args,**kargs)
        end_time = time.time()
        print(end_time-start_time)
return res
return swapper @timer def foo(name,age): print('name:%s,age:%s' %(name,age)) time.sleep(1)
return 123 res = foo(
'mike',18)

 

简单应用

cur_user = {'name':None, 'certify':False}

# 装饰器可以带参数
def certify_choice(choice = 'txt'):
    print('认证方式是:%s' %(choice))
    def certify(func):
        def wrapper(*args, **kargs):
            # 如果已经认证就不需要再认证
            if cur_user['name'] == None and cur_user['certify'] == False:
                name = input('用户名:').strip()
                password = input('登录密码:').strip()
                with open('./用户信息','r') as read_file:
                    for info in read_file:
                        eval_info = eval(info)  # 将取出的字符串转为数据类型
                        #print(eval_info['name'],eval_info['password'])
                        if name == eval_info['name'] and int(password) == eval_info['password']:
                            cur_user['name'] = name
                            cur_user['certify'] = True
                            break
                    else:
                        print('当前用户名或密码错误')
                    read_file.close()
            func(*args, **kargs)
        return wrapper
    return certify

@certify_choice()
def index():
    print('welcome to the page')

@certify_choice()
def home():
    print('this is home page')

@certify_choice()
def shopping():
    print('the track has : milk, fruit, ...')

# 这条语句可以用来调试当前程序的函数
if __name__ == '__main__':
    index()
    home()
    shopping()

 

用户信息
{'name':'a', 'password':111}
{'name':'b', 'password':222}
{'name':'c', 'password':333}
{'name':'d', 'password':444}

 

posted @ 2019-02-22 18:54  狂奔~  阅读(184)  评论(0编辑  收藏  举报