zoukankan      html  css  js  c++  java
  • 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')
    

     

     

      

    一个奋斗中的产品小白
  • 相关阅读:
    js关闭窗口
    利用DotNetZip服务端压缩文件并下载
    .net 文件下载
    js在一定时间内跳转页面及各种页面刷新
    hosts 配置
    js判断字段是否为空 isNull
    js enter键激发事件
    解决iframe在移动端(主要iPhone)上的问题
    17年年终总结——走过2017,迎来2018Flag
    Node.js系列-express(上)
  • 原文地址:https://www.cnblogs.com/dabai123/p/11241830.html
Copyright © 2011-2022 走看看