zoukankan      html  css  js  c++  java
  • Day 11 闭包函数.装饰器

    1.闭包函数:在函数内部定义一个函数,并且内部函数引用了外部函数的变量

    def outer(x,y):   
        def my_max():
            if x > y:  # 引用了outer 的参数,相当与引用了 outer的变量  为闭包函数
                return x
            return y
        return my_max
    
    
    res = outer(80,90)
    print(res())

    2.装饰器: 开放封闭原则(对扩展开放对修改封闭) 

      装饰器必须要遵守两个原则 1:不改变被装饰对象的源代码  2 不改变被装饰对象的调用方法

      插入:time模块:

    def outer(x,y):   
        def my_max():
            if x > y:  # 引用了outer 的参数,相当与引用了 outer的变量  为闭包函数
                return x
            return y
        return my_max
    
    
    res = outer(80,90)
    print(res())
    1. 装饰无参数的函数
      # 需求:装饰器统计函数运行的时间
      import time
      def f():
          time.sleep(1)
          print("我是f")
      
      def outter(func):  # 这里的func形参被传入实参f函数的内存地址
          def inner():
              start = time.time()
              func()  # 这里调用的是最初的f函数
              end = time.time()
              return end - start
          return inner  # 将inner函数的内存地址返回
      
      
      f = outter(f)   # 先执行括号里的,将原f以参数的方式传给outter返回 inner的内存地址,之后调用新定义的f,就等于调用了inner
      print(f())  # f() 就相当于调用了inner
    2. 装饰有参数的函数
      import time
      def f(name):
          time.sleep(1)
          print(f"我是{name}")
      
      def outter(func):   # 这里的func形参被传入实参f函数的内存地址
          def inner(name):  # 参数name是f的参数name
              start = time.time()
              func(name)  # 这里调用的是最初的f函数
              end = time.time()
              return end - start
          return inner
      
      
      f = outter(f)   # 先执行括号里的,将原f以参数的方式传给outter返回 inner的内存地址,之后调用新定义的f,就等于调用了inner
      print(f('yanglingayo'))  # f() 就相当于调用了inner

    3. 装饰器语法糖:语法糖在装饰的时候要紧挨着被装饰函数,当多个装饰器装饰一个函数顺序是重上至下,执行时候时由下至上
      import time
      def outter(func):
          def inner(name):
              start = time.time()
              func(name)
              end = time.time()
              return end - start
          return inner
      
      @outter  # 用@加上装饰器函数名表示,放置于被装饰函数的上方 此时等价与 f = outter(f)
      def f(name):
          time.sleep(1)
          print(f"我是{name}")
      
      
      print(f('yanglingayo'))
    4. 装饰器的模板  
      def outter(func):
          def inner(*args,**kwargs):
              print('执行被装饰函数之前 你可以做的操作')
              res = func(*args,**kwargs)
              print('执行被装饰函数之后 你可以做的操作')
              return res
          return inner
    5. 多个装饰器装饰一个函数
    6. 装饰器最终模板
      from functools import wraps
      def outter(func):
          @wraps(func)  # 装饰器修复技术
          def inner(*args,**kwargs):
              print('执行被装饰函数之前 你可以执行的操作')
              res = func(*args,**kwargs)
              print('执行被装饰函数之后 你可以执行的操作')
              return res
          return inner
    7. 多层装饰器 
      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')

      这个我的理解是把被装饰的函数当作一个中心,他没被装饰一次就在他外面加了一层壳,当我调用执行这个被装饰的函数时,他就像是要拨开这层壳.从外层往里面一层层拨在这个过程会先由外向内的执行每层被装饰函数之前执行的操作,当最终被装饰函数执行完之后 在由内向外的执行每个装饰器在执行完每层被装饰函数的操作,就像用一根针从要穿透一个有3层蛋壳的鸡蛋

      

  • 相关阅读:
    [源码解析] PyTorch 流水线并行实现 (4)--前向计算
    [源码解析] PyTorch 流水线并行实现 (3)--切分数据和运行时系统
    [源码解析] PyTorch 流水线并行实现 (2)--如何划分模型
    [源码解析] PyTorch 流水线并行实现 (1)--基础知识
    [源码解析] 深度学习分布式训练框架 horovod (21) --- 之如何恢复训练
    [源码解析] 深度学习流水线并行 PipeDream(6)--- 1F1B策略
    [源码解析] 深度学习流水线并行 PipeDream(5)--- 通信模块
    [源码解析] 深度学习流水线并行 PipeDream(4)--- 运行时引擎
    6.耐心——想象力决定生产力
    5.权利——自由不等于免费
  • 原文地址:https://www.cnblogs.com/yanglingyao/p/11171746.html
Copyright © 2011-2022 走看看