Python装饰器
2021/8/4 14:06:37
本文主要是介绍Python装饰器,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
目录- 1.装饰器
- 2.装饰器初始
- 2.1 由上方演变的装饰器标准版初
- 2.2 带有返回值的装饰器
- 2.3 带参数的装饰器
- 2.4 万能参数的标准版的装饰器
- 2.5 最终版的装饰器
- 3.装饰器的应用
- 4. 装饰器例子
1.装饰器
- 开放封闭原则
所以装饰器最终最完美的定义就是:在不改变原被装饰的函数的源代码以及调用方式下,为其添加额外的功能。
2.装饰器初始
装饰器就是一个函数
范例
def inex(): time.sleep(2) print("欢迎....") def func(x): def func2(): start_time = time.time() x() #由于传入的实参是index 所以这里是index();下相当于闭包 x是自由变量 end_time = time.time() print(end_time - start_time) return func2 index = func(inex) #代码走到这里会执行 func(index);将index做为实参传给func(x)->func(index);执行完return func2(这个func2也就是里边嵌套的函数) index() #这个也就是执行func2那个函数 >>> 欢迎.... 2.00072979927063
2.1 由上方演变的装饰器标准版初
#定义一个装饰器的函数 def func1(func_name): def func2(): start_time = time.time() func_name() end_time = time.time() print(end_time - start_time) return func2 @func1 #装饰器中的语法糖;这里等用于 index = func1(index);注意此处@func1和下面的def index是结合的 def index(): time.sleep(1) print("欢迎") return 666 index() @func1 #每次需要调用装饰器的时候 都要在此函数头上加上一个@func1(语法糖) def come(): time.sleep(1) print('login') come()
2.2 带有返回值的装饰器
#带有返回值的装饰器 def func2(x): def func3(): start_time = time.time() ret = x() end_time = time.time() print(end_time - start_time) return ret return func3 @func2 #使用语法糖声明装饰器(与下边的func函数) def func(): time.sleep(0.5) print("欢迎登录博客...") return 666 #此返回值是func函数的返回值 ;重点是”func“这个函数是装饰器里边的 x()所调用的 所以要给x()赋一个值 并return ret = func() print(ret) print(func()) >>> 欢迎登录博客... 0.5008265972137451 666 欢迎登录博客... 0.5003719329833984 666
2.3 带参数的装饰器
def func2(x): def func3(name): print(name) start_time = time.time() ret = x(name) end_time = time.time() print(end_time - start_time) return ret return func3 # @func2 #使用语法糖声明装饰器(与下边的func函数) def func(name): time.sleep(0.5) print(f"欢迎登录{name}博客...") return 666 #此返回值是func函数的返回值 ;重点是”func“这个函数是装饰器里边的 x()所调用的 所以要给x()赋一个值 并return ret = func2(func) #执行这部会调用上方的 func2函数 func2的函数返回值是 func3 所以这时 ret 就等于 func3 ret('liu') #执行到这 会调用上方的 fun3函数 并将'liu'传给func3(name)位置参数 再将name传给x(name->'liu') #加上语法糖 def func2(x): def func3(name): print(name) start_time = time.time() ret = x(name) end_time = time.time() print(end_time - start_time) return ret return func3 @func2 #使用语法糖声明装饰器(与下边的func函数) def func(name): time.sleep(0.5) print(f"欢迎登录{name}博客...") return 666 #此返回值是func函数的返回值 ;重点是”func“这个函数是装饰器里边的 x()所调用的 所以要给x()赋一个值 并return func('liu') >>> liu 欢迎登录liu博客... 0.5000627040863037
2.4 万能参数的标准版的装饰器
def func2(x): def func3(*args,**kwargs):#函数的定义 函数的聚合 * args start_time = time.time() ret = x(*args,**kwargs) #函数的执行 * 打散:x(*args) -->x(*(‘liu’,22)) --> x(‘liu’,22) end_time = time.time() print(end_time - start_time) return ret return func3 @func2 #使用语法糖声明装饰器(与下边的func函数) def func(name,age,hobby='运动'): time.sleep(0.5) print(f"欢迎登录{name}{age}岁博客爱好{hobby}...") return 666 #此返回值是func函数的返回值 ;重点是”func“这个函数是装饰器里边的 x()所调用的 所以要给x()赋一个值 并return func('liu',10,hobby='python') # ret = func2(func) #执行这部会调用上方的 func2函数 func2的函数返回值是 func3 所以这时 ret 就等于 func3 # ret('liu') #执行到这 会调用上方的 fun3函数 并将'liu'传给func3(name)位置参数 再将name传给x(name->'liu') @func2 def blog(name,age): print(f'欢迎使用{name},{age}岁的日志功能...') blog('Liu',15) def func2(x): def func3(*args,**kwargs): for i in args: print(i) for k, v in kwargs.items(): print(k, v) start_time = time.time() ret = x(*args,**kwargs) end_time = time.time() print(end_time - start_time) return ret return func3 @func2 #使用语法糖声明装饰器(与下边的func函数) def func(name,age,hobby='运动'): time.sleep(0.5) print(f"欢迎登录{name}{age}岁博客爱好{hobby}...") return 666 #此返回值是func函数的返回值 ;重点是”func“这个函数是装饰器里边的 x()所调用的 所以要给x()赋一个值 并return func('liux',10,hobby='python') # ret = func2(func) #执行这部会调用上方的 func2函数 func2的函数返回值是 func3 所以这时 ret 就等于 func3 # ret('liu') #执行到这 会调用上方的 fun3函数 并将'liux'传给func3(name)位置参数 再将name传给x(name->'liux') @func2 def blog(name,age): print(f'欢迎使用{name},{age}岁的日志功能...') blog('Liu',15)
2.5 最终版的装饰器
def wrapper(f): def inner(*args,**kwargs): ''' 添加额外的功能:执行被装饰函数之前的操作 ''' ret = f(*args,**kwargs) ''' 添加额外的功能:执行被装饰函数之后的操作''' return ret return inner
3.装饰器的应用
实现基于用户登录成功以后才能执行 comment() darit() 函数
user_info = {} def register(): user = input('请输入注册的用户:') passwd = input('请输入注册的密码:') user_info[user] = passwd def login(): count = 1 while count < 4: username = input('请输入您的用户名:') userpasswd = input('请输入您的密码:') if username not in user_info.keys(): print('sorry,您的用户不存在需要注册~') register() elif username in user_info.keys() and userpasswd == user_info.get(username): print('登录成功') return 1 else: print('sorry 输入有误') count += 1 dic = {'status':0} def wrapper(f): def inner(*args,**kwargs): if dic.get('status') == 1: ret = f(*args, **kwargs) else: login_ret = login() if login_ret == 1: dic['status'] =1 ret = f(*args, **kwargs) return inner @wrapper def comment(): print('欢迎访问评论页面.') comment() @wrapper def darit(): print('欢迎访问日记页面') darit()
4. 装饰器例子
def timmer(*args,**kwargs): c = args dct = kwargs def tim(func): def time(*args,**kwargs): print('start...') res = func(*args,**kwargs) print('end...') print(c,dct) # print(name) return res return time return tim @timmer('liu',18,name='liu') #f1=f(f1) def f1(x,y,z): print(f'from f1...{x} {y} {z}') @timmer def f2(x,y,z): print(f'from f1...{x} {y} {z}') return 123 f1(1,2,3)
这篇关于Python装饰器的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-25Python编程基础:变量与类型
- 2024-11-25Python编程基础与实践
- 2024-11-24Python编程基础详解
- 2024-11-21Python编程基础教程
- 2024-11-20Python编程基础与实践
- 2024-11-20Python编程基础与高级应用
- 2024-11-19Python 基础编程教程
- 2024-11-19Python基础入门教程
- 2024-11-17在FastAPI项目中添加一个生产级别的数据库——本地环境搭建指南
- 2024-11-16`PyMuPDF4LLM`:提取PDF数据的神器