Python base (13)

Today the main content

  • Closure
  • Decorator acquaintance
  • Standard Decorators

A, closure

(A) What is closure

  1. Closure: inner variable outer function call is a function closure (not a global variable)

    def func1():
     a = 10
     def func2():
         print(a)  # 内层函数调用外层函数的变量,这就是一个闭包
    
    func1()
  2. A method for detecting closure

    • 函数名.__closure__
    • If the return address of the object is a closure, not a return None closure
    • Note: .__closure__detecting that the function name , the function determines whether the closure
    def func1():
     a = 10
     def func2():
         print(a)  # 调用外层变量a,是闭包
     print(func2.__closure__)  # 判断func2是否是闭包
    
    func1()
    
    运行结果:
    (<cell at 0x00000230F21874F8: int object at 0x0000000063258190>,)
    def func1():
        a = 10
        def func2():
            a = 10
            print(a)  # 使用自身函数变量a,不是闭包
        print(func2.__closure__)
    
    func1()
    
    运行结果:
    None
  3. How to call internal function in the global space

    • Inner function layer function returns the name of the function (memory address), you can call the functions in the global space inside
    def func1():
     a = 10
     def func2():
         print(a)
     return func2  # 返回内层函数的函数名
    
    f = func1()  # 此时f就是func2
    f()  # 调用内层函数func2
    print(f.__closure__)
    
    运行结果:
    10
    (<cell at 0x00000280A87574F8: int object at 0x0000000063258190>,)

(Ii) effect the closure

  1. Data security
  • Vernacular says that if data on the global variable (top grid write code), data security is very low, because everyone can inadvertently modify it, want to solve this problem, we can put the data into the function, it does not call this function, my data is safe. But there is a problem, each time the function finished, the interpreter will automatically empty this function to open up the local space all content (including spatial data opened), so every time a function call to complete, my data is gone, this time it is necessary to use closure. Closures can call the inner function of the variables in the outer function and the inner function If you call the outer function of the variable, then this variable will not die, it will be permanent memory. So, we just need to call in the global space in the closure of the inner function, I can use the data, and data security has improved.
  1. The variable permanent memory, the code for subsequent use

    def outer():
     lst = [1,2,3,4,5]
     def inner():
         return lst
     return inner
    
    f = outer()
    f_lst = f()
    print(f_lst)
    
    运行结果:
    [1,2,3,4,5]

Applications (iii) closure

  • Modified prevent data from being mistakenly
  • Decorator (same format closure)

Second, the decorator acquaintance

(A) six principles of software development (understanding)

  1. Open Closed Principle (Open use Close Principle) - decorator basis
  2. Richter substitution principle (Liskov Substitution Principle)
  3. Dependency Inversion principle (Dependence Inversion Principle)
  4. Interface Segregation Principle (Interface Segregation Principle)
  5. Demeter (the least known principle) (Demeter Principle)
  6. Synthesis of multiplexing principles (Composite Reuse Principle)

(B) decorator basis - the principle of opening and closing

  • Open Closed Principle:
    • Open for extensions
    • To modify the source code closed

(C) introducing decorator

  • I believe most people play LOL, we simulate a game:

    • Like the usual process, ten even kneel ...
    def play_lol():
      print("登陆游戏")
      print("开始排位...")
      print("游戏中...")
      print("失败...")
      print("结束游戏")
    
    play_lol()
    
    运行结果:
    登陆游戏
    开始排位...
    游戏中...
    Virtory
    结束游戏
    • Can not stand, a plug-in to open it, then I need to extend the function, add open before and after the closed plug-in functionality
    def play_lol():
      print("开启外挂!")  # 添加开启外挂功能
      print("登陆游戏")
      print("开始排位...")
      print("游戏中...")
      print("胜利!!!")
      print("结束游戏")
      print("关闭外挂!")  # 添加关闭外挂功能
    
    play_lol()
    
    运行结果:
    开启外挂!
    登陆游戏
    开始排位...
    游戏中...
    胜利!!!
    结束游戏
    关闭外挂!
    • But this time, contrary to the principle of opening and closing, the source code has been modified. Think of a method, the source code before and after packaging, without changing the source code
    def play_lol():
      print("登陆游戏")
      print("开始排位...")
      print("游戏中...")
      print("胜利!!!")
      print("结束游戏")
    
    def new_play():  # 将上面代码前后包装成了一个新的函数,没有改变源码
      print("开启外挂!")
      play_lol()
      print("关闭外挂!")
    
    new_play()
    
    运行结果:
    开启外挂!
    登陆游戏
    开始排位...
    游戏中...
    胜利!!!
    结束游戏
    关闭外挂!
    • Function achieved, and no changes to source code, but there is a problem, we are before accessing the call play_lolthis function, but this time we visit call is new_play()this function is equivalent to changing the call, or contrary to the principle of opening and closing, did not reach extended effect, then we need to make some changes to the code
    def play_lol():
      print("登陆游戏")
      print("开始排位...")
      print("游戏中...")
      print("胜利!!!")
      print("结束游戏")
    
    def wrapper(fn):    # 装饰器雏形
      def inner():
          print("开启外挂!")
          fn()
          print("关闭外挂!")
      return inner
    
    func = wrapper(play_lol)  # 调用装饰器函数将我基础函数传入进去包装
    play_lol = func  # 返回的是包装函数,将包装函数重命名成我原来的函数
    play_lol()  # 调用此函数
    
    运行结果:
    开启外挂!
    登陆游戏
    开始排位...
    游戏中...
    胜利!!!
    结束游戏
    关闭外挂!
    • The code on the lead prototype decorators, plane analysis about:
      • Decorator prototype: the same format as the closure, constituting two functions:
        • The inner function is my wrapper functions to extend the capabilities and functions of the original package together to form a function
        • The role of the outer function is to use the inner function parameter passing, passing is a function of the name of my original function, in the inner call
      • The return value of the decorator return inner: the decorator function that returns the name of the inner function, the real expansion of packaging is the inner function
      • The return value is renamed to the original name of the function: the return value renamed to the original name of the function, in fact, the true role of a wrapper function renamed to the original name of the function, so to solve the problem call the new function, truly followed the the principle of opening and closing, call the original function again actually running is actually inside the inner function decorator
    def wrapper(fn):    # 装饰器雏形
      def inner():
          print("开启外挂!")
          fn()
          print("关闭外挂!")
      return inner
    
    func = wrapper(play_lol)  # 调用装饰器函数将我基础函数传入进去包装
    play_lol = func  # 返回的是包装函数,将包赚函数重命名成我原来的函数
    play_lol()  # 调用此函数
    • The use of syntactic sugar decoration

      • Decorator two lines of code can be converted into syntactic sugar
      func = wrapper(play_lol)  # 调用装饰器函数将我基础函数传入进去包装
      play_lol = func  # 返回的是包装函数,将包赚函数重命名成我原来的函数
      • Syntactic sugar
      @wrapper  # 语法糖
      def play_lol():
          print("登陆游戏")
          print("开始排位...")
          print("游戏中...")
          print("胜利!!!")
          print("结束游戏")
    • In this case, the decorator of the prototype came out

  • Decorator prototype

    def wrapper(fn):
      def inner():
          """扩展功能"""
          fn()
          """扩展功能"""
      return inner
    
    @wrapper
    def func():
      pass
    
    func()
  • Simulation game continues

    • Even hanging open, we have to complete the election hero to enter the game, so we have to pass a basic function parameters, but what we really do is interior decorator inner wrapper function, so they will have to pass parameters inner
    def wrapper(fn):    # 装饰器雏形
      def inner(hero):  # 套到装饰器中内层包装函数参数
          print("开启外挂!")
          fn(hero)  # 基础函数参数
          print("关闭外挂!")
      return inner
    
    @wrapper
    def play_lol(hero):  # 基础函数参数
      print("登陆游戏")
      print("开始排位...")
      print(f"选择英雄:{hero}")
      print("游戏中...")
      print("胜利!!!")
      print("结束游戏")
    
    play_lol("盖伦")
    
    运行结果:
    开启外挂!
    登陆游戏
    开始排位...
    选择英雄:盖伦  # 传入的参数
    游戏中...
    胜利!!!
    结束游戏
    关闭外挂!
    • While hanging open, but still encounter invincible giant pit pit teammates, we have to put him down to report him, so give basis to fill in the return value of the function, while the inner function to fill the real implementation of the return value
    def wrapper(fn):    # 装饰器雏形
      def inner(hero):  
          print("开启外挂!")
          ret = fn(hero)  # 接收基础函数的返回值
          print("关闭外挂!")
          return ret  # 返回包装后的函数的返回值
      return inner
    
    @wrapper
    def play_lol(hero):  # 基础函数参数
      print("登陆游戏")
      print("开始排位...")
      print(f"选择英雄:{hero}")
      print("游戏中...")
      print("胜利!!!")
      print("结束游戏")
      return "坑比队友:xxx"  # 基础函数返回值
    
    print(play_lol("盖伦"))
    
    运行结果:
    开启外挂!
    登陆游戏
    开始排位...
    选择英雄:盖伦
    游戏中...
    胜利!!!
    结束游戏
    关闭外挂!
    坑比队友:xxx  # 返回值
    • This, we decorator standard mode will come out
  • Decorator standard mode (very important)

    def wrapper(fn):
      def inner(*args, **kwargs):
          """扩展功能"""
          ret = fn(*args, **kwargs)
          """扩展功能"""
          return ret
      return inner
    
    @wrapper
    def func():
      pass
    
    func()

Guess you like

Origin www.cnblogs.com/tianlangdada/p/11616788.html