python基础—装饰器

一、什么是装饰器

  装饰器本质就是函数,功能是为其他函数附加功能

二、装饰器遵循的原则

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

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

三、实现装饰器的知识储备

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

示例1:用函数实现

#统计从1加到100所用的时间
import time

def calc(l):
    start_time = time.time()
    res = 0
    for i in l:
        time.sleep(0.1)
        res +=1
    stop_time = time.time()
    print('函数运行时间%s'%(stop_time-start_time))
    return res

calc(range(100))

  运行结果:

函数运行时间10.049538612365723

用装饰器

import time

def timmer(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)
        stop_time = time.time()
        print('函数运行时间为%s'%(stop_time-start_time))
        return res
    return wrapper

@timmer
def calc(l):
    res = 0
    for i in l:
        time.sleep(0.1)
        res += 1
    return res

res = calc(range(100))
print(res)

四、高阶函数

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

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

3.满足上述条件任意一个,都可称之为高阶函数

示例1:函数接收的参数是一个函数名

import time

def foo():
    time.sleep(3)
    print('helloword')

def test(func):
    print(func)
    start_time = time.time()
    func()
    stop_time =time.time()
    print('函数运行时间%s'%(stop_time - start_time))

test(foo)

>>>>>
<function foo at 0x02EBA930>
helloword
函数运行时间3.00070858001709

示例二:接收的参数是一个函数名

#多运行了一次,不合格
import time
def foo():
    time.sleep(3)
    print('来自foo')

def timer(func):
    start_time=time.time()
    func()
    stop_time = time.time()
    print('函数运行时间是  %s' % (stop_time-start_time))
    return func
foo=timer(foo)
foo()
>>>>>

来自foo
函数运行时间是 3.000398635864258
来自foo

示例三:返回的参数是一个函数名

#没有修改被修饰函数的源代码,也没有修改被修饰函数的调用方式,但是也没有为被修饰函数添加新功能
import time
def foo():
    time.sleep(3)
    print('来自foo')

def timer(func):
    start_time=time.time()
    return func
    stop_time = time.time()
    print('函数运行时间是  %s' % (stop_time-start_time))

foo=timer(foo)
foo()

>>>>>>>

  来自foo

结论:高阶函数,满足不了装饰器的功能。

高阶函数总结:

1.函数接收的参数是一个函数名
  作用:在不修改函数源代码的前提下,为函数添加新功能,
  不足:会改变函数的调用方式

2.函数的返回值是一个函数名
  作用:不修改函数的调用方式
  不足:不能添加新功能

五、函数的嵌套

1、什么是函数的嵌套?

    通过在函数内部def的关键字再声明一个函数即为嵌套

def fathar(name):
    def son():
        print('爸爸是%s'%name)
        def grandfathar():
            name = '还是我自己'
            print('爷爷是%s'%name)
        grandfathar()
    son()
fathar('我自己')

>>>>>

  爸爸是我自己
  爷爷是就是我自己

六、闭包

闭包:在一个作用域里放入定义变量,相当于打了一个包

七、无参装饰器

无参装饰器=高级函数+函数嵌套

1.基本框架

def timer(func):
    def wrapper():
        func()

    return wrapper

2、基本装饰器(基本框架+参数+功能+返回值+使用装饰器+语法糖@)

import time

def timmer(func): #func=test
    def wrapper():
        # print(func)
        start_time=time.time()
        func() #就是在运行test()
        stop_time = time.time()
        print('运行时间是%s' %(stop_time-start_time))
    return wrapper

@timmer #test=timmer(test)  #在函数名前面加个@ ,这就是语法糖
def test():
    time.sleep(3)
    print('test函数运行完毕')

test()
# res=timmer(test)  #返回的是wrapper的地址
# res()  #执行的是wrapper()
#
# test=timmer(test)  #返回的是wrapper的地址
# test()  #执行的是wrapper()
#
#  @timmer  就相当于 test=timmer(test)

3.

import time
def timmer(func): #func=test1
    def wrapper(*args,**kwargs): #test('linhaifeng',age=18)  args=('linhaifeng')  kwargs={'age':18}
        start_time=time.time()
        res=func(*args,**kwargs) #就是在运行test()         func(*('linhaifeng'),**{'age':18})
        stop_time = time.time()
        print('运行时间是%s' %(stop_time-start_time))
        return res
    return wrapper

# @timmer #test=timmer(test)
def test(name,age):
    time.sleep(3)
    print('test函数运行完毕,名字是【%s】 年龄是【%s】' %(name,age))
    return '这是test的返回值'

@timmer
def test1(name,age,gender):
    time.sleep(1)
    print('test1函数运行完毕,名字是【%s】 年龄是【%s】 性别【%s】' %(name,age,gender))
    return '这是test的返回值'

# res=test('linhaifeng',age=18)  #就是在运行wrapper
# # print(res)
# test1('alex',18,'male')

test1('alex',18,'male')

八、装饰器应用案例

写一个模拟京东网站,用户认证登录网站和购物加入购物车功能程序

实现功能:用装饰器给所有函数加上验证功能

def index():
    pass

def home():
    pass

def shopping_car()
    pass

def order()
    pass


实现

user_list=[
    {'name':'alex','passwd':'123'},
    {'name':'linhaifeng','passwd':'123'},
    {'name':'wupeiqi','passwd':'123'},
    {'name':'yuanhao','passwd':'123'},
]
current_dic={'username':None,'login':False}

def auth(auth_type='filedb'):
    def auth_func(func):
        def wrapper(*args,**kwargs):
            print('认证类型是',auth_type)
            if auth_type == 'filedb':
                if current_dic['username'] and current_dic['login']:
                    res = func(*args, **kwargs)
                    return res
                username=input('用户名:').strip()
                passwd=input('密码:').strip()
                for user_dic in user_list:
                    if username == user_dic['name'] and passwd == user_dic['passwd']:
                        current_dic['username']=username
                        current_dic['login']=True
                        res = func(*args, **kwargs)
                        return res
                else:
                    print('用户名或者密码错误')
            elif auth_type == 'ldap':
                print('鬼才特么会玩')
                res = func(*args, **kwargs)
                return res
            else:
                print('鬼才知道你用的什么认证方式')
                res = func(*args, **kwargs)
                return res

        return wrapper
    return auth_func

@auth(auth_type='filedb') #auth_func=auth(auth_type='filedb')-->@auth_func 附加了一个auth_type  --->index=auth_func(index)
def index():
    print('欢迎来到京东主页')

@auth(auth_type='ldap')
def home(name):
    print('欢迎回家%s' %name)
#
@auth(auth_type='sssssss')
def shopping_car(name):
    print('%s的购物车里有[%s,%s,%s]' %(name,'奶茶','妹妹','娃娃'))

# print('before-->',current_dic)
# index()
# print('after--->',current_dic)
# home('产品经理')
shopping_car('产品经理')

示例2 :给他加上验证功能装饰器(判断用户和密码,跟字典里的用户和密码进行比对)

user_list=[
    {'name':'alex','passwd':'123'},
    {'name':'linhaifeng','passwd':'123'},
    {'name':'wupeiqi','passwd':'123'},
    {'name':'yuanhao','passwd':'123'},
]
current_dic={'username':None,'login':False}


def auth_func(func):
    def wrapper(*args,**kwargs):
        if current_dic['username'] and current_dic['login']:
            res = func(*args, **kwargs)
            return res
        username=input('用户名:').strip()
        passwd=input('密码:').strip()
        for user_dic in user_list:
            if username == user_dic['name'] and passwd == user_dic['passwd']:
                current_dic['username']=username
                current_dic['login']=True
                res = func(*args, **kwargs)
                return res  #返回值
        else:
            print('用户名或者密码错误')

    return wrapper

@auth_func     #加证功能,也是装饰器
def index():
    print('欢迎来到京东主页')

@auth_func
def home(name):
    print('欢迎回家%s' %name)

@auth_func
def shopping_car(name):
    print('%s的购物车里有[%s,%s,%s]' %(name,'奶茶','妹妹','娃娃'))

print('before-->',current_dic)
index()
print('after--->',current_dic)
home('产品经理')
shopping_car('产品经理')

猜你喜欢

转载自www.cnblogs.com/huiyichanmian/p/8982944.html