一、闭包函数#快速的定制函数
函数内部函数对外部作用域而非全局作用域的引用。
内部函数引用了外部函数的变量
外部函数返回内部函数(或将其传递出去)
def f1(int):
def f2():
pass
return f2
返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域。
计数器
def counter(): # 外部函数
count = 0 # 被闭包"记住"的变量
def increment(): # 内部函数(闭包)
nonlocal count
count += 1
return count
return increment # 返回内部函数
# 使用闭包
c = counter()
print(c()) # 输出: 1
print(c()) # 输出: 2 (记住上次的 count 值)
1
2
快速定制函数
def multiplier(factor): # 外部函数接受参数
def multiply(x): # 闭包捕获外部参数 factor
return x * factor
return multiply
# 创建定制化闭包
double = multiplier(2)
triple = multiplier(3)
print(double(5)) # 输出: 10(5*2)
print(triple(5)) # 输出: 15(5*3)
二、装饰器#具有装饰功能的函数
改变功能的时候不改变原来的调用方式,并且改变原来函数的代码
import time
def sleep(int):
time.sleep(int)
def timetest(func):
def f1(i):
x=time.time()
func(i)
y=time.time()
print(y-x)
return f1
sleep_time = timetest(sleep)
sleep_time(6)
6.0010902881622314
装饰器模板
def outter(func):
def wrapper(*args,**kwargs):
res = func(*args,**kwargs)
return res
return wrapper
语法糖 @
import time
def timetest(func):
def f1(i):
x=time.time()
func(i)
y=time.time()
print(y-x)
return f1
@timetest #sleep_time = timetest(sleep)
def sleep(int):
time.sleep(int)
sleep_time(6)
6.001430511474609
三层装饰器 #给装饰器传参
def f(x):
def outter(func):
def wrapper(*args,**kwargs):
res = func(*args,**kwargs)
return res
return wrapper
return outter
demo = f(x)
pl = demo(func)
pl()
目录导航
menu = {
'北京': {
'海淀': {
'五道口': {
'soho': {},
'网易': {},
'google': {}
},
'中关村': {
'爱奇艺': {},
'汽车之家': {},
'youku': {},
},
'上地': {
'百度': {},
},
},
'昌平': {
'沙河': {
'老男孩': {},
'北航': {},
},
'天通苑': {},
'回龙观': {},
},
'朝阳': {},
'东城': {},
},
'上海': {
'闵行': {
"人民广场": {
'炸鸡店': {}
}
},
'闸北': {
'火车战': {
'携程': {}
}
},
'浦东': {},
},
'山东': {},
}
tag = True
while tag:
menu1 = menu
for key in menu1: # 打印第一层
print(key)
choice1 = input('第一层>>: ').strip() # 选择第一层
if choice1 == 'b': # 输入b,则返回上一级
break
if choice1 == 'q': # 输入q,则退出整体
tag = False
continue
if choice1 not in menu1: # 输入内容不在menu1内,则继续输入
continue
while tag:
menu_2 = menu1[choice1] # 拿到choice1对应的一层字典
for key in menu_2:
print(key)
choice2 = input('第二层>>: ').strip()
if choice2 == 'b':
break
if choice2 == 'q':
tag = False
continue
if choice2 not in menu_2:
continue
while tag:
menu_3 = menu_2[choice2]
for key in menu_3:
print(key)
choice3 = input('第三层>>: ').strip()
if choice3 == 'b':
break
if choice3 == 'q':
tag = False
continue
if choice3 not in menu_3:
continue
while tag:
menu_4 = menu_3[choice3]
for key in menu_4:
print(key)
choice4 = input('第四层>>: ').strip()
if choice4 == 'b':
break
if choice4 == 'q':
tag = False
continue
if choice4 not in menu_4:
continue
# 第四层内没数据了,无需进入下一层
北京
上海
山东
第一层>>: q
menu = {
'北京': {
'海淀': {
'五道口': {
'soho': {},
'网易': {},
'google': {}
},
'中关村': {
'爱奇艺': {},
'汽车之家': {},
'youku': {},
},
'上地': {
'百度': {},
},
},
'昌平': {
'沙河': {
'老男孩': {},
'北航': {},
},
'天通苑': {},
'回龙观': {},
},
'朝阳': {},
'东城': {},
},
'上海': {
'闵行': {
"人民广场": {
'炸鸡店': {}
}
},
'闸北': {
'火车战': {
'携程': {}
}
},
'浦东': {},
},
'山东': {},
}
trigge = 1
print('b:back,q:quit')
while trigge:
for i in menu:
print(i)
choice1 = input('选择路径').strip()
if choice1 == 'q':
break
elif choice1 not in menu:
continue
menu_1 = menu[choice1]
while trigge:
for i in menu_1:
print(i)
choice2 = input('选择路径').strip()
if choice2 == 'b':
break
elif choice2 == 'q':
trigge = 0
break
elif choice2 not in menu_1:
continue
menu_2 = menu_1[choice2]
while trigge:
for i in menu_2:
print(i)
choice3 = input('选择路径').strip()
if choice3 == 'b':
break
elif choice3 == 'q':
trigge = 0
break
elif choice3 not in menu_2:
continue
menu_3 = menu_2[choice3]
while trigge:
for i in menu_3:
print(i)
choice4 = input('选择路径').strip()
if choice4 == 'b':
break
elif choice4 == 'q':
trigge = 0
break
elif choice4 not in menu_3:
continue
while trigge:
print('已是最后一级')
choice5 = input('退出?')
if choice4 == 'b':
break
elif choice4 == 'q':
trigge = 0
continue
b:back,q:quit
北京
上海
山东
选择路径 北京
海淀
昌平
朝阳
东城
选择路径 海淀
五道口
中关村
上地
选择路径 五道口
soho
网易
google
选择路径 soho
已是最后一级
退出? b
soho
网易
google
选择路径 b
五道口
中关村
上地
选择路径 b
海淀
昌平
朝阳
东城
选择路径 b
北京
上海
山东
选择路径
北京
上海
山东
选择路径 q
menu = {
'北京': {
'海淀': {
'五道口': {'soho': {}, '网易': {}, 'google': {}},
'中关村': {'爱奇艺': {}, '汽车之家': {}, 'youku': {}},
'上地': {'百度': {}},
},
'昌平': {
'沙河': {'老男孩': {}, '北航': {}},
'天通苑': {},
'回龙观': {},
},
'朝阳': {},
'东城': {},
},
'上海': {
'闵行': {"人民广场": {'炸鸡店': {}}},
'闸北': {'火车战': {'携程': {}}},
'浦东': {},
},
'山东': {},
}
def navigate_menu(current_data):
"""
一个可以导航任何一层菜单的递归函数。
它会返回一个状态:'quit' 表示需要退出,其他情况正常返回。
"""
while True:
if not current_data:
print("---- 已是最后一级,输入 'b' 返回 ----")
else:
for key in current_data:
print(key)
print("\n提示: 输入 'b' 返回上一级, 输入 'q' 退出程序。")
choice = input("请选择您的路径 > ").strip()
if choice == 'b':
# 返回上一层,函数正常结束,无需返回特殊状态
return
elif choice == 'q':
# 用户想退出,返回一个'quit'信号
return 'quit'
elif choice in current_data:
# --- 递归调用,并捕获其返回值 ---
next_level_data = current_data[choice]
status = navigate_menu(next_level_data)
# --- 关键部分:信号传递 ---
# 如果下一层函数返回了'quit'信号,本层函数也必须立即返回'quit'
# 这样才能把退出信号一路传到最顶层
if status == 'quit':
return 'quit'
else:
print("---- 输入无效,请重新选择! ----")
# --- 程序开始 ---
print("欢迎来到多级菜单系统!")
# 我们在最外层调用函数,并检查最终的返回状态
final_status = navigate_menu(menu)
if final_status == 'quit':
print("程序已退出。")
# 当程序执行到这里时,脚本会自然结束,不会再有输入提示。
欢迎来到多级菜单系统!
北京
上海
山东
提示: 输入 'b' 返回上一级, 输入 'q' 退出程序。
请选择您的路径 > 北京
海淀
昌平
朝阳
东城
提示: 输入 'b' 返回上一级, 输入 'q' 退出程序。
请选择您的路径 > 海淀
五道口
中关村
上地
提示: 输入 'b' 返回上一级, 输入 'q' 退出程序。
请选择您的路径 > 五道口
soho
网易
google
提示: 输入 'b' 返回上一级, 输入 'q' 退出程序。
请选择您的路径 > soho
---- 已是最后一级,输入 'b' 返回 ----
提示: 输入 'b' 返回上一级, 输入 'q' 退出程序。
请选择您的路径 > q
程序已退出。
购物车系统
product_list = [
['Iphone7', 5800],
['Coffee', 30],
['疙瘩汤', 10],
['Python Book', 99],
['Bike', 199],
['ViVo X9', 2499],
]
def denglu():
user_info_dict = {}
while 1:
with open(r'D:/桌面/user_info.txt','r',encoding='utf-8') as fr:
for i in fr:
name = i.split(':')[0]
user_info_dict[name] = i.split(':')[1][:4]
user = input('请输入你的账号:').strip()
if user in user_info_dict:
password = input('请输入四位密码:')
if user_info_dict[user] == password:
print(f'{user} 欢迎')
return user
break
else :
buch = input('没有搜索到该账号,是否要注册Y&N ?')
if buch == 'Y':
while 1:
new_password = input('请输入四位密码')
new_password1 = input('再次输入以确认')
if new_password == new_password1:
break
print('两次输入不一致!')
with open(r'D:/桌面/user_info.txt','a',encoding='utf-8') as fa:
fa.write(f'\n{user}:{new_password}')
print('注册成功!')
elif buch == 'N':
continue
user = denglu()
tatal = int(input('今天想消费多少钱?').strip())
tatal0 = tatal
shopping_dict = {}
print(f'尊敬的用户{user},您的余额为{tatal}元,祝您购物愉快!')
product_dict = {}
j=0
for i in product_list:
j+=1
product_dict[str(j)] = i
print(product_dict)
while 1:
choice1 = input('你想买什么?(输入q退出)').strip()
if choice1 in product_dict:
num1 = int(input('买多少?').strip())
tatal1 = tatal - num1*product_dict[choice1][1]
if tatal1 < 0:
print('钱不够')
else:
if choice1 not in shopping_dict:
shopping_dict[product_dict[choice1][0]] = num1
else:
shopping_dict[product_dict[choice1][0]] += num1
tatal = tatal1
print(f'你还剩{tatal}元')
elif choice1 == 'q':
print(f'''
您购买的商品列表
{product_dict}
你共消费{tatal0-tatal}元
您的余额为{tatal}元
欢迎下次再来
''')
break
else:
print('没有该商品')
浙公网安备 33010602011771号