zoukankan      html  css  js  c++  java
  • nonlocal关键字、装饰器

    nonlocal关键字

    # 作用:将 L 与 E(E中的名字需要提前定义) 的名字统一
    
    # 应用场景:如果想在被嵌套的函数中修改外部函数变量(名字)的值
    
    # 案例:
    
    def outer():
        num = 10
        print(num)  # 10 
        def inner():
            nonlocal num
            num = 20
            p77rint(num)  # 20
        inner()
        print(num)  # 20

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

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

    装饰器

    # 把要被装饰的函数作为外层函数的参数通过闭包操作后返回一个替代版函数
    # 被装饰的函数: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("原有功能")

    有参有返的函数被装饰

    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)

    带参装饰器:了解

    # 了解
    def outer(input_color):
        def wrap(fn):
            if input_color == 'red':
                info = '33[36;41mnew action33[0m'
            else:
                info = 'yellow:new action'
    
            def inner(*args, **kwargs):
                pass
                result = fn(*args, **kwargs)
                print(info)
                return result
            return inner
        return wrap  # outer(color) => wrap
    
    
    color = input('color: ')
    @outer(color)  # @outer(color) ==> @wrap  # func => inner
    def func():
        print('func run')
    
    func()

    登录认证功能

    is_login = False  # 登录状态
    
    def login():
        usr = input('usr: ')
        if not (len(usr) >= 3 and usr.isalpha()):
            print('账号验证失败')
            return False
        pwd = input('pwd: ')
        if usr == 'abc' and pwd =='123qwe':
            print('登录成功')
            is_login = True
        else:
            print('登录失败')
            is_login = False
    
    
    # 完成一个登录状态校验的装饰器
    def check_login(fn):
        def inner(*args, **kwargs):
            # 查看个人主页或销售功能前:如果没有登录先登录,反之可以进入其功能
            if is_login != True:
                print('你未登录')
                login()
            # 查看个人主页或销售
            result = fn(*args, **kwargs)
            return result
        return inner
    
    # 查看个人主页功能
    @check_login
    def home():
        print('个人主页')
    
    # 销售功能
    @check_login
    def sell():
        print('可以销售')
    
    home()
  • 相关阅读:
    A Color Game
    《算法分析》作业1
    The 2018 ACM-ICPC CCPC NING XIA G-Factories
    2017北京ICPC Pangu and Stones(区间DP)
    Comet OJ
    2019牛客多校训练营第四场补题
    2019牛客多校训练营第五场补题
    2017CCPC哈尔滨 B:K-th Number(二分+尺取)
    启发式分治入门 Non-boring sequences UVA
    2019牛客多校训练营第三场补题
  • 原文地址:https://www.cnblogs.com/tyler-bog/p/10643580.html
Copyright © 2011-2022 走看看