装饰器

1.装饰器的概念:
        1)装饰器的组成:
            装饰器 = 高阶函数+嵌套函数+语法糖
        2)装饰器的原理:
            装饰器实际上就是为了给程序增添功能。(大前提:不修改被装饰的函数的源代码和调用方式)

2.高阶函数:
    高阶函数的形式有两种:
        1)把一个函数名当作实参传给另外一个函数(“实参高阶函数”)
        2)返回值中包含函数名(“返回值高阶函数”)
        示例:

import time
def func():
    time.sleep(1)
    print('ceshi')
def call_func(func):
    start = time.time()
    func()
    stop = time.time()
    print(stop-start)
func = call_func(func)
print(func)

3.函数嵌套:在一个函数中再次创建一个函数

例:

def test():
            print('这是第一层函数输出')
            def secend_test():
                print('这是第二层函数输出')
            secend_test()
        print(test())
    错误示例:
        def first():
            print('aaa')
        def second():
            print('bbb')
            first()
        second()
    #这是调用不是嵌套

4.装饰器的简单应用:

import time
def timer(func):
    def run_time():
        start = time.time()
        func()
        stop = time.time()
        print('函数运行时间为:',start-stop)
    return run_time
@timer
def test():
    a = 0
    time.sleep(1)
    for i in range(10000):
        a += i
    print(a)
test()

5.装饰器为什么需要两层嵌套?

def test(func):                #1
    def test1():            #2
        func()                #3
        print('22:48')        
    return test1            #4
@test                        #5
def date():                    #6
    print('2018.12.17')
date()


            上面是一个简单的装饰器,它分为两层,
            外层a#1 定义装饰器的名称,参数为被装饰的函数a,#4 return装饰后的函数,即内层函数b;
            内层b#2引入函数date的参数,并进行修饰.

            当程序运行到#4时,装饰器test开始执行,此时外层a相当于一个函数,运行函数时发现return,开始运行内层#2,此时a已经指向了b,此后再调用a,就会调用b

            双层装饰器的意义:
                一是两层结构可以传递被装饰的函数a的参数
                二是不改变函数原来的结构,因为装饰器本身就是一个函数,他与其他函数有相同的执行顺序

6.装饰器添加返回值案例

def test(func):
    def test1():
        res = func()
        print('22:48')
        return res
    return test1
@test
def date():
    print('2018.12.17')
    return 'aaa'
print(date())

7.函数带有参数的案例:

def test(func):
    def wrapper(*args,**kwargs):
        print('garbage')
        res = func(*args,**kwargs)
        return res
    return wrapper
@test
def garbage(recycled,unrecoverable):
    print(recycled)
    print(unrecoverable)
    return 'Everyone in this room is rubbish'
print(garbage('paper','plastic'))

7.解压数列:

l = [1,254,6465753523,45,24,52,3]
a,*b,c=l        #注:a代表第一个元素,b代表中间的元素,c代表最后一个元素
print(a)
print(c)
print(b)

8.给函数添加认证功能:

    在进入网购页面中,有的页面是需要你登录才能够正常的显示,下面的示例中,购物车和订单函数模拟为相关页面,需要登录才能进行相关操作

login_status = False
def validation(func):
    def wrapper(*args, **kwargs):
        global login_status
        if login_status == True:
            res = func(*args, **kwargs)
            return res
        else:
            username = input('用户名:').strip()
            passwd = input('密码:').strip()
            if username == 'Jiang' and passwd == 'Feng':
                #global login_status
                login_status = True
                res = func(*args, **kwargs)
                return res
            else:
                print('你输入的用户名或密码错误!')
    return wrapper

def index():
    print('this is index')

@validation
def shopping_car():
    print('this is shopping_car')

@validation
def order(name):
    print('this is order')

index()
shopping_car()
order('Jiang_Feng')


-------升级版
user_list = [
    {'name':'aaa','passwd':'aaa'},
    {'name':'bbb','passwd':'bbb'},
    {'name':'ccc','passwd':'ccc'}
]

login_status = {'username':None,'status':False}
def validation(func):
    def wrapper(*args, **kwargs):
        if login_status['status'] == True:
            res = func(*args, **kwargs)
            return res
        else:
            username = input('用户名:').strip()
            passwd = input('密码:').strip()
            for user_log in user_list:
                if user_log['name'] == username and user_log['passwd'] == passwd:
                    login_status['status'] = True
                    res = func(*args, **kwargs)
                    return res
            else:
                print('你输入的用户名或密码错误!')
    return wrapper

def index():
    print('this is index')

@validation
def shopping_car():
    print('this is shopping_car')

@validation
def order(name):
    print('this is %s order'%name)

index()
shopping_car()
order('Jiang_Feng')

9.装饰器带有参数案例:登录时的认证选择

def auth(authentication = 'HTTP Digest'):        #默认的认证方式
    def validation(func):
        def wrapper(*args, **kwargs):
            if authentication == 'HTTP Digest':
                pass
            elif authentication == 'HTTP Basic':
                pass
        return wrapper
    return validation()
@auth(authentication = 'HTTP Basic')      #选择的认证方式
def order(name):
    print('this is order')
order()
posted @ 2018-12-18 22:40  better_feng  阅读(167)  评论(0编辑  收藏  举报