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

原则:

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

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

装饰器的知识储备

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

 

#装饰器:
def timmer(func):
    def wrapper(*args,**kwargs):
        time1=time.time()
        res=func(*args,**kwargs)
        time2=time.time()
        print('函数的运行时间是%d'%(time2-time1))
        return res
    return wrapper


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

a=cal(range(10))

print(a)

>>>函数的运行时间是1
45

 

高阶函数定义:

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

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

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

 

import time

def foo():
    time.sleep(0.5)
    print("sadfa")

def test(func):
    print(func)
    t1=time.time()
    func()
    t2=time.time()
    print("函数的运行时间是%ds"%(t2-t1))

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

 

#不修改源代码
#不修改foo调用方式
#多运行了一次,不合格
def foo():
    time.sleep(1)
    print("from the foo")

def dec(func):
    t1=time.time()
    func()
    t2=time.time()
    print("%s的运行时间是%d"%(func,(t2-t1)))
    return func

foo=dec(foo)
foo()


函数的闭包:闭包是由函数及其相关的引用环境组合而成的实体,如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。

def father(name):
    print('from father %s'%name)
    def son():
        print('my father is %s'%name)
        def grandson():
            print('my grandpa is %s'%name)
        grandson()
    son()
    print(locals())

father('alex')


>>>from father alex
my father is alex
my grandpa is alex
{'son': <function father.<locals>.son at 0x00000169A59B7268>, 'name': 'alex'}


装饰器框架:

#装饰器框架
def timmer(func):
    def wapper():
        print(func)
        func()
    return wapper
def timmer_test(func):
    def add_time():
        t1=time.time()
        func()
        t2=time.time()
        print('该函数的运行时间是%d'%(t2-t1))
    return add_time

def test():
    time.sleep(2)
    print('test函数运行完毕')


test=timmer_test(test)
test()

>>>test函数运行完毕 该函数的运行时间是2

 

@语法糖:

def timmer(func):
    def add_time():
        t1=time.time()
        func()
        t2=time.time()
        print('该函数的运行时间是%d'%(t2-t1))
    return add_time

@timmer#@timmer 就相当于test=timmer(test)
def test():
    time.sleep(2)
    print('test函数运行完毕')

test()

>>>test函数运行完毕
该函数的运行时间是2


函数闭包加上返回值:

def timmer(func):
    def add_time():
        t1=time.time()
        res=func()
        t2=time.time()
        print('该函数的运行时间是%d'%(t2-t1))
        return res
    return add_time

@timmer#@timmer 就相当于test=timmer(test)
def test():
    time.sleep(2)
    print('test函数运行完毕')
    return '这是test的返回值'

res=test()#这里就是在运行add_time
print(res)


>>>test函数运行完毕
该函数的运行时间是2
这是test的返回值


再加上参数:

def timmer(func):
    def add_time(*args,**kwargs):
        t1=time.time()
        res=func(*args,**kwargs)
        t2=time.time()
        print('该函数的运行时间是%d'%(t2-t1))
        return res
    return add_time

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

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

res=test('alex',19)#这里的test是运行的add_time
print(res)
res1=test1('sb',20,'male')
print(res1)


>>>test函数运行完毕,名字是alex,年龄是19
该函数的运行时间是2
这是test的返回值
test1函数运行完毕,名字是sb,年龄是20,性别是male
该函数的运行时间是3
这是test1的返回值

 

解压序列:

a,b,c='hel'
print(a,b,c)


e,f,g=(4,5,6)
print(e,f,g)



#取出第一个值和最后两个值
l=['alex',7,8,9,7,8,5,2,1,5,6,4,8,6,4,6,'is','sb']

#*_代表中间所有的值,_可以换成任意值
x,*_,y,z=l
print(x,y,z)

>>>h e l
4 5 6
alex is sb


调换两变量的值:

a=20
b=100
a,b=b,a
print(a,b)

>>>100 20

 

装饰器加上验证功能:

 

user_dic={'name':None,'login':False}

def yanzheng(func):
    global zt
    def wapper(*args,**kwargs):
        if user_dic['name'] and user_dic['login']:
            res=func(*args,**kwargs)
            return
        name=input('请输入用户名:').strip()
        psw=input('请输入密码:').strip()
        if  name=='alex' and psw=='123':
            res=func(*args,**kwargs)
            user_dic['name']=name
            user_dic['login']=True
            return res
        else:
            print('用户名或密码错误')
    return wapper

@yanzheng
def index():
    print('欢迎来到京东主页')

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

@yanzheng
def car(name):
    print('%s的购物车里有%s'%(name,'奶茶'))

index()
home('alex')
car('alex')

>>>请输入用户名:alex
请输入密码:123
欢迎来到京东主页
欢迎回家alex
alex的购物车里有奶茶

 

user_list=[
    {'user_name':'alex','psw':'123'},
    {'user_name':'blex','psw':'456'},
    {'user_name':'clex','psw':'789'},
    {'user_name':'dlex','psw':'0'}

]



current_zt={'name':None,'login':False}

def yanzheng(func):
    def wapper(*args,**kwargs):
        global user_name
        if current_zt['name'] and current_zt['login']:
            res=func(*args,**kwargs)
            return res
        user_name=input('请输入用户名:').strip()
        psw=input('请输入密码:').strip()
        for user_dic in user_list:
            if  user_name==user_dic['user_name'] and psw==user_dic['psw']:
                res=func(*args,**kwargs)
                current_zt['name']=user_name
                current_zt['login']=True
                return res
        else:
            print('用户名或密码错误')
    return wapper

@yanzheng
def index():
    print('欢迎来到京东主页')

@yanzheng
def home():
    print('欢迎回家%s'%user_name)

@yanzheng
def car():
    print('%s的购物车里有%s'%(user_name,'奶茶'))

index()
home()
car()

>>>请输入用户名:blex
请输入密码:456
欢迎来到京东主页
欢迎回家blex
blex的购物车里有奶茶

 

将原装饰器加上参数:直接在最外层加一个函数带上参数,使用装饰器时也需带上参数

user_list=[
    {'user_name':'alex','psw':'123'},
    {'user_name':'blex','psw':'456'},
    {'user_name':'clex','psw':'789'},
    {'user_name':'dlex','psw':'0'}

]



current_zt={'name':None,'login':False}


def renzhen(type='ldb'):
    def yanzheng(func):
        def wapper(*args,**kwargs):
            global user_name
            print('认证类型是%s'%type)
            if type=='ldb':
                if current_zt['name'] and current_zt['login']:
                    res=func(*args,**kwargs)
                    return res
                user_name=input('请输入用户名:').strip()
                psw=input('请输入密码:').strip()
                for user_dic in user_list:
                    if  user_name==user_dic['user_name'] and psw==user_dic['psw']:
                        res=func(*args,**kwargs)
                        current_zt['name']=user_name
                        current_zt['login']=True
                        return res
                else:
                    print('用户名或密码错误')
            elif type=='abb':
                print('不知道这个类型')
                res = func(*args, **kwargs)
                return res
            else:
                print('类型错误')
                res = func(*args, **kwargs)
                return res
        return wapper
    return yanzheng

@renzhen(type='ldb')
def index():
    print('欢迎来到京东主页')

@renzhen(type='abb')
def home():
    print('欢迎回家%s'%user_name)

@renzhen(type='sss')
def car():
    print('%s的购物车里有%s'%(user_name,'奶茶'))

index()
home()
car()

 

posted on 2019-04-01 18:01  Manuel  阅读(188)  评论(0编辑  收藏  举报