• Day 12 装饰器,开发封闭.


    一、什么是装饰器

    装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象。

    装饰器的应用场景:比如插入日志,性能测试,事务处理,缓存等等场景。

    二、装饰器的形成过程

    import time
    def func1():
    print("in func1")
    def timer(func):
    def inner():
    start =time.time()
    func()
    print(time.time()-start)
    return inner()

    func1=timer(func1)
    func1()
    但是如果有多个函数,我都想让你测试他们的执行时间,你每次是不是都得func1 = timer(func1)? 这样会有点麻烦,因为这些函数的函数名有可能是不通的 ,有func1 ,func2,graph等等
    所以更简单的方法,python给提供了, 那就是魔法糖.

    import time
    def timer(func):
        def inner():
            start = time.time()
            func()
            print(time.time() - start)
        return inner
    
    @timer   #==> func1 = timer(func1)
    def func1():
        print('in func1')
    
    
    func1()

    三、带参数的装饰器.

    import time
    def timer(func):
        def inner(*args,**kwargs):
            start = time.time()
            re = func(*args,**kwargs)
            print(time.time() - start)
            return re
        return inner
    
    @timer   #==> func1 = timer(func1)
    def func1(a,b):
        print('in func1')
    
    @timer   #==> func2 = timer(func2)
    def func2(a):
        print('in func2 and get a:%s'%(a))
        return 'fun2 over'
    
    func1('aaaaaa','bbbbbb')
    print(func2('aaaaaa'))



    四、开放,封闭原则

    1.对扩展是开放的

        为什么要对扩展开放呢?

        我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。

    2.对修改是封闭的

        为什么要对修改封闭呢?

        就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。

    装饰器完美的遵循了这个开放封闭原则。

    五、装饰器的主要功能和固定结构

    def timer(func):
        def inner(*args,**kwargs):
            '''执行函数之前要做的'''
            re = func(*args,**kwargs)
            '''执行函数之后要做的'''
            return re
        return inner

    from functools import wraps
    
    def deco(func):
        @wraps(func) #加在最内层函数正上方
        def wrapper(*args,**kwargs):
            return func(*args,**kwargs)
        return wrapper
    六、带参数的装饰器

    假如你有成千上万个函数使用了一个装饰器,现在你想把这些装饰器都取消掉,你要怎么做?

    一个一个的取消掉? 没日没夜忙活3天。。。

    过两天你领导想通了,再让你加上。。。

    带参数的装饰器.

    def outer(flag):
        def timer(func):
            def inner(*args,**kwargs):
                if flag:
                    print('''执行函数之前要做的''')
                re = func(*args,**kwargs)
                if flag:
                    print('''执行函数之后要做的''')
                return re
            return inner
        return timer
    
    @outer(False)
    def func():
        print(111)
    
    func()
    七、多个装饰器修饰一个函数.

    def outer(flag):
        def timer(func):
            def inner(*args,**kwargs):
                if flag:
                    print('''执行函数之前要做的''')
                re = func(*args,**kwargs)
                if flag:
                    print('''执行函数之后要做的''')
                return re
            return inner
        return timer
    
    @outer(False)
    def func():
        print(111)
    
    func()
    复制代码
     
    
    返回顶部
    多个装饰器装饰同一个函数
    
    有些时候,我们也会用到多个装饰器装饰同一个函数的情况。
    
    
    复制代码
    def wrapper1(func):
        def inner():
            print('wrapper1 ,before func')
            func()
            print('wrapper1 ,after func')
        return inner
    
    def wrapper2(func):
        def inner():
            print('wrapper2 ,before func')
            func()
            print('wrapper2 ,after func')
        return inner
    
    @wrapper2
    @wrapper1
    def f():
        print('in f')
    
    f()
    输出结果:

    wrapper2 ,before func
    wrapper1 ,before func
    in f
    wrapper1 ,after func
    wrapper2 ,after func



  • 相关阅读:
    smobiler介绍(二)
    smobiler介绍(一)
    iOS JS 交互之利用系统JSContext实现 JS调用OC方法以及Objective-C调用JavaScript方法
    iOS 力学动画生成器UIKit Dynamics 之碰撞效果讲解
    iOS 解决tableView中headerView头部视图不跟随tableView滑动的方法
    iOS 当使用FD_FullscreenPopViewController的时候遇到scrollView右滑手势无法使用的解决
    iOS 点击左上角系统返回按钮方法
    解决右滑返回手势和UIScrollView中的手势冲突
    Git 常见的命令操作
    iOS Class 使用NSProxy和NSObject设计代理类的差异
  • 原文地址:https://www.cnblogs.com/mengbin0546/p/8418938.html
Copyright © 2020-2023  润新知