python课堂整理21---初识装饰器

一、装饰器:

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

原则:

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

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

一个简单的装饰器

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 cal(l):
    res = 0
    for i in l:
        time.sleep(0.01)
        res += i
    return res
ret = cal(range(200))
print(ret)

二、装饰器的知识储备

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

高阶函数定义:

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

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

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

用高阶函数模拟装饰器:

结果多运行了一次

import time
def foo():
    time.sleep(3)
    print('来自foo')

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

  

三、 函数嵌套及闭包

嵌套就是,函数里再定义函数

闭包:闭----->封装的变量   包----->一层层函数

每个包找变量先从自身那层开始找,找不到再从外层找

重点:函数即变量

def father(name):
    
    def son():
        print('我的爸爸是%s' %name)
        def grandson():
            name = 'China'
            print('我的爷爷是%s' %name)
        grandson()
    son()
father('河南')

装饰器框架

def timmer(func):
    def wrapper():
        #增加功能
        func()

    return wrapper
    

补充该装饰器架子

import time
def timmer(func):
    def wrapper():
        #增加功能
        start_time = time.time()
        func()
        stop_time = time.time()
        print('运行时间是%s'%(stop_time - start_time))
    return wrapper

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

res = timmer(test)  #返回的是wrapper的地址
res()  #执行的是wrapper()

可以看出,只要把函数的最后两行代码的函数接收值改为:test

test= timmer(test)

test() 

看起来符合装饰器原则

但每次给函数增加功能都得写一遍 test= timmer(test),显然不合理

所以,用@timmer 去代替test = timmer(test)

import time
def timmer(func):
    def wrapper():
        #增加功能
        start_time = time.time()
        func()
        stop_time = time.time()
        print('运行时间是%s'%(stop_time - start_time))
    return wrapper
@timmer  #就相当于:test = timmer(test)
def test():
    time.sleep(2)
    print('test函数运行完毕')
test()

四、加上返回值的装饰器

import time
def timmer(func):
    def wrapper():
        #增加功能
        start_time = time.time()
        res = func()   #这里执行的函数test,所以要在这里给函数一个接收返回值的变量
        stop_time = time.time()
        print('运行时间是%s'%(stop_time - start_time))
        return res   #这里要返回test的返回值
    return wrapper
@timmer  #就相当于:test = timmer(test)
def test():
    time.sleep(2)
    print('test函数运行完毕')
    return '这是test的返回值'
a = test()
print(a)

五、加上参数的装饰器

import time
def timmer(func):
    def wrapper(*args, **kwargs):   #可接受任意值
        #增加功能
        start_time = time.time()
        res = func(*args, **kwargs)  #将wrapper接受的值原封传给func
        stop_time = time.time()
        print('运行时间是%s'%(stop_time - start_time))
        return res
    return wrapper
@timmer  #就相当于:test = timmer(test)
def test1(name, age, gander):
    time.sleep(2)
    print('test1运行结果名字为%s年龄为%d性别为%s'%(name, age, gander))
    return '这是test1的返回值'
a = test1('jinling', 20, 'female')
print(a)

@timmer    
def test2(name, age):
    time.sleep(3)
    print('test2函数运行结果名字为%s年龄为%d'%(name, age))
    return '这是test2的返回值'
b = test2('liuwen', 18)
print(b)

六、实现一个验证功能装饰器

def func_ver(func):
    def wrapper(*args, **kwargs):
        name1 = input('请输入用户名:')
        pd = input('请输入用户密码:')
        if name1 == 'PJL' and pd == '123':
            func(*args, **kwargs)
        else:
            print('用户名或密码错误')

    return wrapper




@func_ver
def index():
    print('欢迎来到的我的网站')
@func_ver
def home(name):
    print('%s欢迎回家'%name)
@func_ver
def secrect(name):
    print('%s这是你的小秘密'%name)


index()
home('jinling')
secrect('jining')

 

 

  

posted @ 2019-07-26 12:26  绝世刘  阅读(211)  评论(0编辑  收藏  举报