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,装饰过就不能修改参数的值
- First look decorative and syntactic sugar
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
@wrapper2
decorative objective functionfunc()
, which is regarded as the decoration finish as a whole, the upper being decorator@wrapper1
Decorative - Returns: complete implementation of the objective function will return the value to the nearest first anti-decorator objective function
@wrapper2
inside the inner packaging function, then after the@wrapper2
return value to the decorator inner layer of the packaging functions inside the@wrapper1
interior 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 functioninner
package with a wrapper function inner decoratorinner
, the decorator and the inner wrapper function ofinner
packaging 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,而传入的目标函数是:目标函数
- From the inside looking out, first with a first layer decorator
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
Factorial of n
def factorial(n): if n == 1: return 1 return factorial(n - 1) * n print(factorial(5)) 运行结果: 120
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]
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
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]
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)
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))
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)