Python3基础-装饰器

1、装饰器的介绍

1、装饰:被装饰对象添加新的功能,器 代指 器具/工具
2、装饰器:本质是函数,作用在不修改被装饰对象源代码和调用方式的前提下被装饰对象添加额外的功能
3、函数装饰器 分为: 无参装饰器、有参装饰器
4、函数嵌套+闭包+函数对象 == 装饰器

2、例子

为下述函数添加统计其执行时间的功能

import  time
def test(res):
    time.sleep(3)
    for i in range(10):
        res += 1
    return  res

test(10) #函数执行

高阶函数=》装饰器

import  time
def test(res):
    time.sleep(3)
    for i in range(10):
        res += 1
    return  res

def testfunc(func):
    start_time=time.time() #开始运行时间
    func(10)
    stop_time=time.time()  #结束运行时间
    sumtime=stop_time-start_time
    print('run time is %s'%sumtime)

testfunc(test)  
#若是其他函数需要统计函数运行时间,则也需要统一改成  testfunc(其他函数) 
#没有遵循不修改被装饰对象的调用方式
#无参装饰器
def test():
    time.sleep(3)
    print("泥是谁吖。。。。")

def testfunc(func):
    return  func

res=testfunc(test)
res()
#若被装饰的是一个有参函数,便会抛出异常
#有参装饰器
import  time
def timer(func):
    def wapper(*args,**kwargs):#引用外部作用域的变量 func
        start_time = time.time()  # 开始运行时间
        res=func(*args,**kwargs)
        stop_time = time.time()  # 结束运行时间
        sumtime = stop_time - start_time
        print("函数运行时间%s"%sumtime)
        return  res
    return wapper

@timer
def test(res):
    time.sleep(3)
    for i in range(10):
        res += 1
    return  res
test(10) #函数执行

闭包

如果在一个函数的内部定义了另一个函数,外部的函数叫它外函数,内部的函数叫它内函数
1 、在一个外函数中定义了一个内函数。
2 、内函数里运用了外函数的临时变量。
3 、并且外函数的返回值是内函数的引用。
#testouter是外部函数,x和y都是外函数的临时变量
def testouter(x):
    y=10
    #inner是内部函数
    def inner():
        #在内函数中,用到了外函数的临时变量
        print("输入的值:%d"%(x+y))
    #外函数的返回值是内函数的引用
    return  inner
demo=testouter(5)
#此时外函数两个临时变量 x是5 y是10 ,并创建了内函数,然后把内函数的引用返回存给了demo
# 外函数结束的时候发现内部函数将会用到自己的临时变量,这两个临时变量就不会释放,会绑定给这个内部函数
demo()
 # demo存了外函数的返回值,也就是inner函数的引用,这里相当于执行inner函数

"""
总结
1、一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。 2、闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。 """

 ======================================================================================================================================================

{'username':'susu','passwd':'123'}
{'username':'susu1','passwd':'123'}
{'username':'susu2','passwd':'123'}
{'username':'susu3','passwd':'123'}
{'username':'susu4','passwd':'123'}
filedb文件内容
#登录认证
current_dic={'username':None,'login':False}  #类似登录session 保存登录信息  只要登录一次就保存

def auth(auth_type='filedb'):
    def auth_func(func):
        def wrapper(*args,**kwargs):
            print('认证类型',auth_type)
            if current_dic['username'] and current_dic['login']:  #判断是否已登录
                res = func(*args,**kwargs)
                return  res
            name=input("请输入账号>>>").strip()
            passwd=input("请输入密码 >>>").strip()
            if auth_type =='filedb':                  #判断读取文件类型
                with open('filedb','r+') as f:         #打开文件
                    for line in f:                 #一行一行的读取文件
                        user_dict=eval(line)       #字符串类型转换成字典类型
                        # print('-----',user_dict)
                        if name == user_dict['username'] and passwd ==user_dict['passwd']:
                            current_dic['username'] = name
                            current_dic['login'] = True
                            res = func(*args, **kwargs)
                            return res
                    else:
                        print("账号和密码错误")
            elif auth_type == 'ldap':
                print("不知道什么类型数据哭")
        return wrapper
    return auth_func

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

@auth(auth_type='ldap')
def home(name):
    print("hi,%s.下午好"%name)

@auth(auth_type='filedb')
def shopping_cart(name):
    print("hi,%s,你的购物车里面有上衣、玻璃球、飞机玩具"%name)

print('after--->',current_dic)
inder()
# home('susu')
# shopping_cart('XiaoSu')
print('before--->',current_dic)
posted @ 2019-10-22 20:09  槑槑DE  阅读(302)  评论(0编辑  收藏  举报