• 10 Day Python之装饰器


    装饰器

    1、开放封闭原则

    开放:对于添加新功能是开放的

    封闭:对于修改原功能是封闭的

    2、装饰器的作用

    在不更改原函数调用方式的前提下对原函数添加新功能

    3、装饰器

    # ①引子——为什么要有装饰器
    为了在不修改原函数的基础上为函数添加新功能,产生了装饰器
    
    # ②简单装饰器
    def deco(f):
        def wrapper():
            """原函数前添加的功能"""
            f()
            """原函数后添加的功能"""
        return wrapper
    
    def func():
        print('这是原函数!')
    
    func = deco(func)
    func()
    
    # ③装饰器的语法糖
    def deco(f):
        def wrapper():
            """原函数前添加的功能"""
            f()
            """原函数后添加的功能"""
        return wrapper
    
    @deco # ——>此处效果等同于 func = deco(func)
    def func():
        print('这是原函数')
    
    func()
    
    # ④带返回值的装饰器
    def deco(f):
        def wrapper():
            """原函数前添加的功能"""
            res = f()
            """原函数后添加的功能"""
            return res
        return wrapper
    
    @deco
    def func():
        print('这是原函数')
    
    func()
    
    # ⑤带参数、带返回值的装饰器
    def deco(f):
        def wrapper(*args,**kwargs):
            """原函数前添加的功能"""
            res = f(*args,**kwargs)
            """原函数后添加的功能"""
            return res
        return wrapper
    
    @deco
    def func(*args,**kwargs):
        print('这是原函数')
    
    func(*args,**kwargs)
    
    # ⑥多层装饰器
    # todo
    
    # ⑦多个装饰器修饰同一个函数
    # todo

    4、装饰器的固定格式

    def deco(f):
        def wrapper(*args,**kwargs):
        """原函数前添加的功能"""
        res = f(*args,**kwargs)
        """原函数后添加的功能"""
        return res
        return wrapper
    
    @deco
    def func(*args,**kwargs):
        pring('这是原函数')
    
    func(*args,**kwargs)

    5、装饰器的固定格式—wraps版

    如果想使用原函数的双下方法,则需要再调用系统装饰器@ wraps(func)

    from functools import wraps
    
    def deco(func):
        @wraps(func) #加在最内层函数正上方
        def wrapper(*args,**kwargs):
            return func(*args,**kwargs)
        return wrapper
    
    @deco
    def origin_func():
        '''
        这是原函数的注释
        :return:
        '''
        print('这是原函数')
    
    # 虽然已经执行了装饰器,origin_func已经指向wrapper,但是如果用了@wraps(func)装饰器之后调用origin_func的双下方法依然是原函数origin_func的
    print(origin_func.__name__)
    >>> origin_func
    
    print(origin_func.__doc__)
    >>> 这是原函数的注释
    >>> :return:

    6、带参数的装饰器

    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) —> 返回timer —>@timer —>func = timer(func) —> func = inner
    @outer(False) 
    def func():
        print(111)
    
    func()

    7、多个装饰器装饰同一个函数

    def wrapper1(func):
        def inner1():
            print('wrapper1 ,before func')
            func()
            print('wrapper1 ,after func')
        return inner1
    
    def wrapper2(func):
        def inner2():
            print('wrapper2 ,before func')
            func()
            print('wrapper2 ,after func')
        return inner2
    
    @wrapper2 # 将inner1进行装饰,即inner1 = wrapper2(inner1) = inner2
    @wrapper1 # 先执行这个装饰器,即f = wrapper1(f) = inner1
    def f():
        print('in f')
    
    f()
    
    # 结果
    >>> wrapper2 ,before func
    >>> wrapper1 ,before func
    >>> in f
    >>> wrapper1 ,after func
    >>> wrapper2 ,after func
  • 相关阅读:
    Prof. Dr. Ligang Liu (刘利刚) 中国科技大学
    Chi-Wing FU, Philip
    LinuxROS与Android哪个重要?
    深圳市智汇机器人科技有限公司&环宇智行
    【泡泡机器人公开课预告】刘艺博-三维视觉与深度学习
    VS配置FFmpeg开发环境
    VS搭建Boost编程环境
    C++ 多线程编程解决CPU占用率高问题
    C++ 调节PCM音频音量大小
    C++ 采集音频流(PCM裸流)实现录音功能
  • 原文地址:https://www.cnblogs.com/lidaxu/p/8146546.html
Copyright © 2020-2023  润新知