12.Python(装饰器)

一、定义

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

原则:

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

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

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

二、高阶函数

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

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

3.满足上述其中一个条件就是高阶函数

下例中是一个高阶函数:

def foo():
    print("你好")

def test(func):#是一个高阶函数
    print(func)#func有了foo的内存地址
    func()#运行foo函数
test(foo)

 

 

def foo():
    print("来自foo")

def test(func):#接收参数是函数名
    func()
    return func#返回值还是函数名
foo=test(foo)
foo()#还是执行原来函数的调用方式

 

 三、装饰器实现

1、基本实现

import time

def timmer(func): #func=test
    def wrapper():
        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()  #执行的是wrapper()

 

 2、原本的函数有返回值

import time

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

@timmer  #test=timmer(test)
def test():
    time.sleep(3)
    print('test函数运行完毕')
    return "这是test的返回值"

res = test()  
print(res)

 

 3、加上参数

import time
def timmer(func): #func=test1
    def wrapper(*args, **kwargs): #固定用法,不管原函数有几个参数,这种形式都能接收
        start_time = time.time()
        res = func(*args, **kwargs) #就是在运行test1()  func(*('alex'),**{'age':18;'gender':male;....})
        stop_time = time.time()
        print('运行时间是%s' % (stop_time-start_time))
        return res
    return wrapper

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

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

 

4、验证功能

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']:#有人开始登录,没人登录的话就直接不往下运行了
            return 0
        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:#for也可以加else,说明for循环中没有匹配的
                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('产品经理')

 5、带参数验证功能装饰器

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']:
                    return 0
                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') 
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,'奶茶','妹妹','娃娃'))


index()
home('产品经理')
shopping_car('产品经理')

 

posted @ 2020-10-11 16:20  最近饭吃的很多  阅读(87)  评论(0编辑  收藏  举报