• 闭包函数及装饰器


    一.闭包函数

    闭包函数:

    1.闭:定义在函数内部的函数
    2.包:内部函数引用了外部函数作用域的名字

    可以用闭包来给函数传参

    def outter(x):
        def inner():
            print(x)
            return 100
    
        return inner
    
    
    res = outter(1233)
    
    print(res())
    View Code

    二.装饰器

    装饰器就是闭包函数的一种应用场景

    1.为什么要用装饰器

    开放封闭原则:
          开放:对扩展开放
          封闭:对修改封闭

    2.装饰器简介

    装饰器(可调用对象)需要遵守的两个原则:
    1.不改变被调用装饰对象的源码
    2.不改变被调用装饰对象调用方式

    装饰器的目标:为可调用对象增加新的功能。(就像是给一个丑陋的盒子,用一层精美的包装自装扮起来)

    2.装饰器模板

     装饰器的通用写法

    无参

    from functools import wraps
    
    def outter(func):
        @wraps(func)
        def built_inner(*args, **kwargs):
            print("函数执行之前的操作")
    
            res = func(*args, **kwargs)
            print("函数执行之后的操作")
            return res
    
        return built_inner
    
    @outter
    def index():
        print("index")
    
    
    index()
    print(help(index))  # 查看函数的注释
    print(index.__name__)
    View Code

    有参

    from functools import wraps
    
    
    def wrapper(source):
        def outter(func):
    
            @wraps(func)
            def built_inner(*args, **kwargs):
                print("函数执行之前的操作")
    
                res = func(*args, **kwargs)
                print("函数执行之后的操作")
                return res
    
            return built_inner
    
        return outter
    
    
    @wrapper(1)
    def index():
        print("index")
        
    
    index()
    print(help(index))  # 查看函数的注释
    print(index.__name__)
    View Code

    3.语法糖

    @outter  # @outter 等价于 for_rang = outter(for_rang) 
    def for_rang():
        time.sleep(1)
        for i in range(1, 10):
            for j in range(1, i + 1):
                print("%s*%s=%2s " % (i, j, i * j), end="")
            print()
    View Code

    语法糖在书写的时候应该与被调用的对象紧紧挨着 ,两者之间不要有空行。

    4.多层装饰器 

    装饰器在装饰顺序    从下往上
    装饰器执行时顺序    从上往下

    def outter1(func1):
        print('加载了outter1')
        def wrapper1(*args,**kwargs):
            print('执行了wrapper1')
            res1=func1(*args,**kwargs)
            return res1
        return wrapper1
    def outter2(func2):
        print('加载了outter2')
        def wrapper2(*args,**kwargs):
            print('执行了wrapper2')
            res2=func2(*args,**kwargs)
            return res2
        return wrapper2
    def outter3(func3):
        print('加载了outter3')
        def wrapper3(*args,**kwargs):
            print('执行了wrapper3')
            res3=func3(*args,**kwargs)
            return res3
        return wrapper3
    @outter1  # index = outter1(wapper2)
    @outter2  # wrapper2 = outter2(wrapper3)
    @outter3  # wrapper3 = outter3(最原始的index函数内存地址)
    def index():
        print('from index')
    
    index()
    View Code

    5.装饰器的伪装

    用户查看被装饰函数的函数名和注释时看到的就是被装饰函数和它的注释

    from functools import wraps
    
    def outter(func):
        @ wraps(func)
        def get_time(*args, **kwargs):
            """
            this is get_time
            :param args: 
            :param kwargs: 
            :return: 
            """
            start = time.time()
            res = func(*args, **kwargs)
            end = time.time()
            print(end - start)
            return res
        return get_time
    def wrapper1(func):
        @wraps(func)
        def confirm_(*args, **kwargs):
            """
            this is confirm
            :param args: 
            :param kwargs: 
            :return: 
            """
            username = input("username>>:").strip()
            psw = input("password>>:").strip()
            if username == "jason" and psw == "123":
                res = func(*args, **kwargs)
                return res
            else:
                print("输出错误")
        return confirm_
    View Code
  • 相关阅读:
    C# Trace 信息写入日志文件
    C# 获取操作系统版本和Service Pack版本的方法
    C# 控制系统服务
    log4net记录日志过程中一直占用日志文件的解决方法
    FileStream类学习小结
    Centos7 部署.net core2.1 详细步骤
    linux 安装redis 完整步骤
    Asp.Net Core Linux环境下 找不到配置文件、静态文件的问题
    关于Clipboard剪切板获取值为NULL问题解决方法
    STA和MTA线程模式的区别
  • 原文地址:https://www.cnblogs.com/Cpsyche/p/11171134.html
Copyright © 2020-2023  润新知