zoukankan      html  css  js  c++  java
  • 闭包函数及装饰器

    一.闭包函数

    闭包函数:

    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
  • 相关阅读:
    力扣算法:组合总和IV
    力扣算法:组合总和III
    逻辑回归(Logistic Regression)学习笔记
    力扣算法:组合总和II
    力扣算法:组合总和
    寒假作业(五)
    寒假作业(四)
    寒假作业(三)
    寒假作业(二)
    寒假学习(一)
  • 原文地址:https://www.cnblogs.com/Cpsyche/p/11171134.html
Copyright © 2011-2022 走看看