zoukankan      html  css  js  c++  java
  • Python学习之路——装饰器

    开放封闭原则:不改变调用方式与源代码上增加功能

    '''
    1.不能修改被装饰对象(函数)的源代码(封闭)
    2.不能更改被修饰对象(函数)的调用方式,且能达到增加功能的效果(开放)
    '''
    View Code

    装饰器

    # 把要被装饰的函数作为外层函数的参数通过闭包操作后返回一个替代版函数
    # 被装饰的函数:fn
    # 外层函数:outer(func)  outer(fn) => func = fn
    # 替代版函数: return inner: 原功能+新功能
    
    def fn():
        print("原有功能")
    
    # 装饰器
    def outer(tag):
        def inner():
            tag()
            print(新增功能")
        return inner
    fn = outer(fn)              
                  
    fn()

    语法糖@外层函数

    def outer(f):
        def inner():
            f()
            print("新增功能1")
        return inner
                  
    def wrap(f):
        def inner():
            f()
            print("新增功能2")
        return inner              
    
    @wrap  # 被装饰的顺序决定了新增功能的执行顺序
    @outer  # <==> fn = outer(fn): inner      
    def fn():
        print("原有功能")
    View Code

    有参有返的函数被装饰

    def check_usr(fn):  # fn, login, inner:不同状态下的login,所以参数是统一的
        def inner(usr, pwd):
            # 在原功能上添加新功能
            if not (len(usr) >= 3 and usr.isalpha()):
                print('账号验证失败')
                return False
            
            # 原有功能
            result = fn(usr, pwd)
            
            # 在原功能下添加新功能
            # ...
            
            return result
           return inner
    
    
    @check_usr
    def login(usr, pwd):
        if usr == 'abc' and pwd =='123qwe':
            print('登录成功')
            return True
        print('登录失败')
        return False
    
    # 总结:
    # 1.login有参数,所以inner与fn都有相同参数
    # 2.login有返回值,所以inner与fn都有返回值
    
    """
    inner(usr, pwd):
        res = fn(usr, pwd)  # 原login的返回值
        return res
    
    
    login = check_usr(login) = inner
    
    res = login('abc', '123qwe')  # inner的返回值
    """

    装饰器最终写法

    def wrap(fn):
        def inner(*args, **kwargs):
            print('前增功能')
            result = fn(*args, **kwargs)
            print('后增功能')
            return result
        return inner
    
    @wrap
    def fn1():
        print('fn1的原有功能')
    @wrap
    def fn2(a, b):
        print('fn2的原有功能')
    @wrap   
    def fn3():
        print('fn3的原有功能')
        return True
    @wrap
    def fn4(a, *, x):
        print('fn4的原有功能')
        return True
    
    fn1()
    fn2(10, 20)
    fn3()
    fn4(10, x=20)
  • 相关阅读:
    2.4 学习总计 之 自己实现底部导航
    2.3 学习总结 之 分页查询
    2.2 学习总结 之 servlet 的两次抽取
    Rocket
    Rocket
    Rocket
    Rocket
    Rocket
    Rocket
    Rocket
  • 原文地址:https://www.cnblogs.com/king-home/p/10679729.html
Copyright © 2011-2022 走看看