标签:rap sea factor 递归函数 line 天津 元素 app 今天
def wrapper(fn):
def inner(*args, **kwargs):
"""扩展内容"""
ret = fn(*args, **kwargs)
"""扩展内容"""
return inner
@wrapper
def func():
pass
func()
回顾一下之前的游戏模拟,通过装饰器给我的游戏过程扩展了开挂的功能,装饰之后每次想玩游戏的时候调用函数都会给你先把挂打开,此时你的游戏函数已经被装饰了,但是现在有一个问题,我今天想自己玩一把,不想开挂了,怎么办?我们可以给装饰器传一个参数,来控制我的装饰器的开启和关闭就可以了
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
刨析一下:
@wrapper_outer(True)
先执行函数调用,函数调用返回的是我内层装饰器的函数名,相当于@wrapper
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) # 先执行函数调用
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,装饰过就不能修改参数的值
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()
执行原理:从里到外进行包装
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
刨析一下:
@wrapper2
装饰目标函数func()
,装饰完将其看作成一个整体,在被上层装饰器@wrapper1
装饰@wrapper2
内部的inner包装函数中,之后再将@wrapper2
内部的inner包装函数的返回值返回给上一层装饰器@wrapper1
内部的inner中,最终得到的返回值是我调用函数的返回值inner
,而最外层装饰器中的包装函数inner
包装着内层装饰器的包装函数inner
,而内层装饰器的包装函数inner
包装着真正的目表函数func
# 伪代码:
def 装饰器1(传入目标函数):
def 内层包装函数1,也是真正执行的函数(目标函数的参数):
"""前扩展功能"""
目标函数(目标函数的参数)
"""后扩展功能"""
return 包装函数的函数名
def 装饰器2(传入目标函数):
def 内层包装函数2,也是真正执行的函数(目标函数的参数):
"""前扩展功能"""
目标函数(目标函数的参数)
"""后扩展功能"""
return 包装函数的函数名
@装饰器1
@装饰器2
def 目标函数(形参):
函数体
目标函数(实参)
# 真正执行过程:
先执行:装饰器1的内层包装函数1,而传入的目标函数是:装饰器2的内层包装函数2
再执行:装饰器2的内层包装函数2,而传入的目标函数是:目标函数
如果只是在不断的调用自己本身,没有一个明确的结束条件,那么就是一个死递归(无限循环)。
Python官方规定,为了避免无限制的调用自己本身,递归的最大深度为1000(最多只能调用自己本身1000次),实际递归深度为998
def func():
print(1)
func()
func()
运行结果:
[Previous line repeated 994 more times]
1
1
1
...(共打印998个1)
可以通过导入sys模块,修改最大递归深度
import sys
sys.setrecursionlimit(100) # 修改递归深度
def func():
print(1)
func()
func()
运行结果:
[Previous line repeated 94 more times]
1
1
1
...(实际打印98个1)
求n的阶乘
def factorial(n):
if n == 1:
return 1
return factorial(n - 1) * n
print(factorial(5))
运行结果:
120
计算斐波那契序列
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]
打印列表嵌套的每一个元素
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
给列表去重,不能使用集合
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]
遍历文件夹中所有的文件
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)
二分查找
# 普通递归版本?二分法
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))
三级菜单进入返回
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)
标签:rap sea factor 递归函数 line 天津 元素 app 今天
原文地址:https://www.cnblogs.com/tianlangdada/p/11619068.html