python基础之多层语法糖、函数递归
一、多层语法糖
| 1.语法糖的语法要点: |
| 语法糖会'将紧挨着的被装饰对象的名字'当作'参数'自动'传入装饰器'中,然后将'返回的结果重新赋值'给'原函数名' |
| 2 多层语法糖: |
| 装饰顺序由上往下,遇到最后一个才会将与函数名相同的变量名传给装饰器函数调用 |
| 也就是说,每次执行之后如果上面还有语法糖 则直接将返回值函数名传给上面的语法糖,如果上面没有语法糖了, 则变形最终套娃的结果在案例中为' index = outter1(wrapper2) ' |
| |
| |
| |
| |
| def outter1(func1): |
| print('加载了outter1') |
| def wrapper1(*args, **kwargs): |
| print('执行了wrapper1') |
| res1 = func1(*args, **kwargs) |
| return res1 |
| return wrapper1 |
| |
| def outter2(func2): |
| print('加载了outter2') |
| def wrapper2(*args, **kwargs): |
| print('执行了wrapper2') |
| res2 = func2(*args, **kwargs) |
| return res2 |
| return wrapper2 |
| |
| def outter3(func3): |
| print('加载了outter3') |
| def wrapper3(*args, **kwargs): |
| print('执行了wrapper3') |
| res3 = func3(*args, **kwargs) |
| return res3 |
| return wrapper3 |
| |
| |
| @outter1 |
| @outter2 |
| @outter3 |
| def index(): |
| print('from index') |
| index() |
二、装饰器模版
| 1. 无参装饰器 |
| def outer(func): |
| def inner(*args, **kwargs): |
| |
| res = func(*args, **kwargs) |
| |
| return res |
| return inner |
| |
| @outer |
| def index(): |
| pass |
| |
| index() |
| |
| |
| 2. 有参装饰器 |
| 有参装饰器的目的仅仅是给装饰器传递额外的参数 |
| |
| def outer_plus(mode): |
| def outer(func): |
| def inner(*args, **kwargs): |
| |
| res = func(*args, **kwargs) |
| |
| return res |
| return inner |
| |
| @outer_plus('mode') |
| def func1(): |
| pass |
有参装饰器案例:校验用户是否登陆装饰器
| |
| def outer(mode): |
| def login_auth(func_name): |
| def inner(*args, **kwargs): |
| username = input('username>>>:').strip() |
| password = input('password>>>:').strip() |
| if mode == '1': |
| print('数据直接写死') |
| elif mode == '2': |
| print('数据来源于文本文件') |
| elif mode == '3': |
| print('数据来源于字典') |
| elif mode == '4': |
| print('数据来源于MySQL') |
| return inner |
| return login_auth |
| '''当装饰器中需要额外的参数时>>>:有参装饰器''' |
| |
| """ |
| 函数名加括号执行优先级最高 有参装饰器的情况 |
| 先看函数名加括号的执行 |
| 然后再是语法糖的操作 |
| """ |
| |
| def index(): |
| print('from index') |
| index() |
| |
| |
| def func(): |
| print('from func') |
| func() |
装饰器语法优先级:
1 函数名加括号执行优先级最高,在有参装饰器的情况下,先看函数名加括号的执行
2 然后再是语法糖的操作
三、装饰器修复技术
| 1.在定义装饰器前填写代码: |
| from functools import wraps |
| 2.在装饰器中的外层函数代码体中,调用内置的装饰器 @wraps(func_name) |
| |
| |
| |
| from functools import wraps |
| def outer(func_name): |
| @wraps(func_name) |
| def inner(*args, **kwargs): |
| """这里装饰器中的函数inner""" |
| res = func_name(*args, **kwargs) |
| return res |
| return inner |
| |
| @outer |
| def func(): |
| """这里说原始的func函数""" |
| pass |
| |
| |
| help(func) |
| print(func) |
| func() |
| --------------------运行结果--------------------- |
| Help on function func in module __main__: |
| |
| func() |
| 这里说原始的func函数 |
| |
| <function func at 0x102d789d0> |
四、函数的递归调用
1.函数的递归调用
| 1.直接调用:函数在定义中调用自己 |
| def index(): |
| print('from index') |
| index() |
| index() |
| |
| |
| |
| 2.间接调用:函数在彼此的定义中调用彼此 |
| def index(): |
| print('from index') |
| func() |
| def func(): |
| print('from func') |
| index() |
| func() |
| |
| |
| 3.最大递归深度:1000 |
| |
| count = 0 |
| def index(): |
| global count |
| count += 1 |
| print(count) |
| index() |
| index() |
| '''官网提供的最大递归深度为1000,我们在测试的时候可能会出现996 997''' |
2.递归函数的定义
| 递归函数定义: |
| 1 直接或者间接调用自己 |
| 2 每次调用都必须比上一次简单,并且需要有一个明确结束条件 |
3.递归函数的特点
| 1.必须有一个明确的结束条件; |
| 2.每次进入更深一层递归时,问题规模相比上次递归都应有所减少; |
| 3.相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入); |
| 4.直接或间接的调用自身的函数,递归效率不高 |
4.递归函数
| |
| |
| |
| |
| """ |
| 假设有五个同学,编号从1-5,1号同学的年龄为十八岁,用递归函数如何得到5号同学的年龄 |
| """ |
| def get_age(number): |
| if number == 1: |
| return 18 |
| return get_age(number - 1) + 2 |
| |
| |
| real_age = get_age(5) |
| print(real_age) |
| 作业: |
| 1.昨日作业回顾 |
| |
| is_login = False |
| |
| |
| def login_auth(func_name): |
| def inner(*args, **kwargs): |
| global is_login |
| if is_login: |
| res = func_name(*args, **kwargs) |
| return res |
| username = input('username>>>:').strip() |
| password = input('password>>>:').strip() |
| if username == 'jason' and password == '123': |
| is_login = True |
| res = func_name(*args, **kwargs) |
| return res |
| else: |
| print('用户名或密码错误无法执行函数') |
| return inner |
| |
| |
| @login_auth |
| def register(): |
| print('注册功能') |
| |
| |
| @login_auth |
| def login(): |
| print('登录功能') |
| |
| |
| @login_auth |
| def shopping(): |
| print('购物功能') |
| |
| |
| register() |
| login() |
| shopping() |
| |
| 2.今日作业 |
| |
| |
| l1 = [1, [2, [3, [4, [5, [6, [7, [8, ]]]]]]]] |
| |
| |
| def get_list(l): |
| for i in l: |
| if type(i) == list: |
| get_list(i) |
| else: |
| print(i) |
| |
| |
| get_list(l1) |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY