Python basis (xiv)

Today the main content

  • Decorative extension
    • There are parameters decorator
    • A plurality of decorative function decorator
  • Recursion

A decorative extension

(A) with parameters decorator

  • First look at the standard mode decorator

    def wrapper(fn):
      def inner(*args, **kwargs):
          """扩展内容"""
          ret = fn(*args, **kwargs)
          """扩展内容"""
      return inner
    
    @wrapper
    def func():
      pass
    
    func()
  • Recall simulation game before, by decorator to me during the game extends the functionality hanging open, then decorate each want to play the game when you first call the function will be to hang open, then your game functions have been decorated , but now there is a question, I want to play one myself today, I do not want to hang up, how to do? We can pass a parameter to the decorator, to control my decorator on and off on it

    def wrapper_outer(argv):  # 给装饰器加一个参数,控制装饰器开启关闭
        def wrapper(fn):
            def inner(hero): 
                if argv:  # 如果是True执行添加装饰
                    print("开启外挂!")
                    ret = fn(hero)
                    print("关闭外挂!")
                    return ret
                else:  # 如果是False,执行原函数
                    ret = fn(hero)
                    return ret
            return inner
        return wrapper
    
    @wrapper_outer(True)
    def play_lol(hero):  # 基础函数参数
      print("登陆游戏")
      print("开始排位...")
      print(f"选择英雄:{hero}")
      print("游戏中...")
      print("胜利!!!")
      print("结束游戏")
      return "坑比队友:xxx"  # 基础函数返回值
    
    print(play_lol("盖伦"))
    
    运行结果:
    开启外挂!
    登陆游戏
    开始排位...
    选择英雄:盖伦
    游戏中...
    胜利!!!
    结束游戏
    关闭外挂!
    坑比队友:xxx
    • Analysis about the plane:

      • First look decorative and syntactic sugar
        • @wrapper_outer(True)First function call, the function call returns the name of the function my inner decorator, equivalent to@wrapper
        • Decorator outermost portion of the inner parameter controls whether the function is performed inside the inner wrapper function, argv if true, performing the equivalent of packaging, argv if false, the implementation of the primitive
      • It is in effect through to the decorator mass participation played a decorative function control
      def wrapper_outer(argv):
          def wrapper(fn):
              def inner(hero):  
                  if argv:  # 为真执行这里
                      print("开启外挂!")
                      ret = fn(hero)
                      print("关闭外挂!")
                      return ret
                  else:  # 为假执行这里
                      ret = fn(hero)
                      return ret
              return inner
          return wrapper
      
      @wrapper_outer(True)  # 先执行函数调用
      • Note: Once decorated to the function, parameter decorator can not change, because the reason for the closure of parameters have been closed inside, can only be called the inner function, can not be modified outermost decorator parameters
      flag = True
      def wrapper_outer(argv):
          def wrapper(fn):
              def inner(*args, **kwargs):  
                  if argv:
                      """扩展功能"""
                      ret = fn(*args, **kwargs)
                      """扩展功能"""
                      return ret
                  else:
                      ret = fn(*args, **kwargs)
                      return ret
              return inner
          return wrapper
      
      @wrapper_outer(flag)
      def func():
          pass
      
      flag = False
      func()  # 此时flag依然是True,装饰过就不能修改参数的值
  • Reference standard mode decorators

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

(B) a plurality of decorative function decorator

  • The implementation of the principle: packaging from the inside out

    def wrapper1(fn):
      def inner(*args, **kwargs):
          print("扩展功能1")
          ret = fn(*args, **kwargs)
          print("扩展功能4")
          return ret
      return inner
    
    def wrapper2(fn):
      def inner(*args, **kwargs):
          print("扩展功能2")
          ret = fn(*args, **kwargs)
          print("扩展功能3")
          return ret
      return inner
    
    @wrapper1
    @wrapper2
    def func():
      print("目标函数")
    
    func()
    
    运行结果:
    扩展功能1
    扩展功能2
    目标函数
    扩展功能3
    扩展功能4
    • Analysis about the plane:

      • From the inside looking out, first with a first layer decorator @wrapper2decorative objective function func(), which is regarded as the decoration finish as a whole, the upper being decorator @wrapper1Decorative
      • Returns: complete implementation of the objective function will return the value to the nearest first anti-decorator objective function @wrapper2inside the inner packaging function, then after the @wrapper2return value to the decorator inner layer of the packaging functions inside the @wrapper1interior of the inner the return value is that I end up calling function's return value
      • The final objective function call is in fact the real implementation of the outermost decorator wrapper function inner, while the outermost decorator wrapper function innerpackage with a wrapper function inner decorator inner, the decorator and the inner wrapper function of innerpackaging a real the head table functionfunc
      # 伪代码:
      
      def 装饰器1(传入目标函数):
          def 内层包装函数1,也是真正执行的函数(目标函数的参数):
              """前扩展功能"""
              目标函数(目标函数的参数)
              """后扩展功能"""
          return 包装函数的函数名
      
      def 装饰器2(传入目标函数):
          def 内层包装函数2,也是真正执行的函数(目标函数的参数):
              """前扩展功能"""
              目标函数(目标函数的参数)
              """后扩展功能"""
          return 包装函数的函数名
      
      @装饰器1
      @装饰器2
      def 目标函数(形参):
          函数体
      
      目标函数(实参)
      
      # 真正执行过程:
      先执行:装饰器1的内层包装函数1,而传入的目标函数是:装饰器2的内层包装函数2
      再执行:装饰器2的内层包装函数2,而传入的目标函数是:目标函数

Second, recursive

(A) What is recursive

  • First is a recursive function, as long as the function is to meet two requirements recursive function:
    • Continue to call itself
    • There are definite end condition

(B) recursion depth

  • If you just continue to call themselves, without a clear end condition, it is a dead recursive (infinite loop).

  • Python official regulations, in order to avoid unlimited calls itself a maximum depth of recursion is 1000 (can only call themselves 1000), the actual depth of recursion 998

    def func():
        print(1)
        func()
    
    func()
    
    运行结果:
    [Previous line repeated 994 more times]
    1
    1
    1
    ...(共打印998个1)
  • By introducing sys module, modify the maximum depth of recursion

    import sys
    sys.setrecursionlimit(100)  # 修改递归深度
    
    def func():
        print(1)
        func()
    
    func()
    
    运行结果:
    [Previous line repeated 94 more times]
    1
    1
    1
    ...(实际打印98个1)

(C) applied recursively

  1. Factorial of n

    def factorial(n):
        if n == 1:
            return 1
        return factorial(n - 1) * n
    
    print(factorial(5))
    
    运行结果:
    120
  2. Computing Fibonacci sequence

    def fib(n):
     if n <= 2:
         return 1
     return fib(n-1) + fib(n-2)
    
    print(list(map(fib,range(1, 6))))
    
    运行结果:
    [1, 1, 2, 3, 5]
  3. Print nested lists each element

    l1 = [1, 2, [3, 4, [5, [6, 7, [8, 9], 10], 11, 12], 13], 14, 15]
    
    def func(lst):
        for el in lst:
            if type(el) == list:
                func(el)
            else:
                print(el, end=" ")
    
    func(l1)
    
    运行结果:
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
  4. Go to the list of heavy, you can not use aggregate

    l1 = [1, 1, 2, 3, 4, 5, 6, 3, 3, 5, 6, 3, 4, 5]
    
    def del_repetition(lst):
        for el in lst:
            if lst.count(el) > 1:
                lst.remove(el)
                del_repetition(lst)
    
    del_repetition(l1)
    print(l1)
    
    运行结果:
    [1, 2, 6, 3, 4, 5]
  5. All files Traverse Folder

    import os
    
    def read(filepath, n):
        files = os.listdir(filepath)  # 获取到当前文件夹中的所有文件
        for fi in files:  # 遍历文件夹中的文件, 这里获取的只是本层文件名
            fi_d = os.path.join(filepath, fi)  # 加入文件夹 获取到文件夹文件
            if os.path.isdir(fi_d):  # 如果该路径下的文件是文件夹
                print("\t" * n, fi)
                read(fi_d, n + 1)  # 继续进行相同的操作
            else:
                print("\t" * n, fi)  # 递归出口. 最终在这里隐含着return
    
    # 递归遍历目录下所有文件
    read('../day16/', 0)
  6. Binary search

    # 普通递归版本⼆二分法
    lst = [22, 33, 44, 55, 66, 77, 88, 99, 101, 238, 345, 456, 567, 678, 789]
    n = 567
    left = 0
    right = len(lst) - 1
    
    def binary_search(n, left, right):
        if left <= right:
            middle = (left + right) // 2
            if n < lst[middle]:
                right = middle - 1
            elif n > lst[middle]:
                left = middle + 1
            else:
                return middle
            return binary_search(n, left, right)  
            # 这个return必须要加. 否则接收到的永远是None.
        else:
            return -1
    
    print(binary_search(567, 0, len(lst) - 1))
  7. Return into the three-level menu

    menu = {
        '北京': {
            '海淀': {
                '五道口': {
                    'soho': {},
                    '网易': {},
                    'google': {}
                },
                '中关村': {
                    '爱奇艺': {},
                    '汽车之家': {},
                    'youku': {},
                },
                '上地': {
                    '百度': {},
                },
            },
            '昌平': {
                '沙河': {
                    '北邮': {},
                    '北航': {},
                },
                '天通苑': {},
                '回龙观': {},
            },
            '朝阳': {},
            '东城': {},
        },
        '上海': {
            '闵行': {
                "人民广场": {
                    '炸鸡店': {}
                }
            },
            '闸北': {
                '火车战': {
                    '携程': {}
                }
            },
            '浦东': {},
        },
        '天津': {
            "和平": {
                "小白楼": {},
                "五大道小洋楼": {},
                "滨江道": {},
            },
            "南开": {
                "天大": {},
                "南开": {},
                "理工": {},
            },
            "河北": {
                "天津之眼": {},
                "海河": {},
                "意式风情区": {},
                "世纪钟": {},
                "大悲院": {},
            },
        },
    }
    
    def menu_func(menu):
        while True:
            for k in menu:
                print(k)
            key = input('input>>').strip()
            if key == 'b' or key == 'q':
                return key
            elif menu.get(key):
                ret = menu_func(menu[key])
                if ret == 'q': 
                    return 'q'
    
    menu_func(menu)

Guess you like

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