python装饰器
在python中所有东西都是对象,都是object,函数也不例外
装饰器本身就是一个可调用的函数,装饰器也叫语法糖,在闭包的基础上实现
装饰器的作用:不影响原因函数的功能,还能添加新的功能
装饰器语法
#定义装饰器函数
def decorator():
...
@decorator #使用@加装饰器函数名,给my_func使用decorator装饰器
def my_func():
...
假设我们有一个A函数,我们要在函数执行前输出start,函数结束执行时输出end
如果不使用装饰器在函数内直接输出
def a_func():
print('start')
v = (1, 2, 3,)
print('end')
return v
使用装饰器实现
def func1(func): # 外部闭包函数的参数是被装饰的函数对象
def func2():
print('start')
res = func() # 外部函数接收的参数,被装饰函数的调用
print(res)
print('end')
return res
return func2
@func1
def a_func():
v = (1, 2, 3,)
return v
a_func()
'''
执行流程:
相当于 func1(a_func)() 把a_func传递给func1再调用一下
1.func1将被装饰的函数当做参数传递过去
2.func1 返回了func2对象
3.func2对象内部 print start
4.实例func() 相当于实例a_func()调用
5.打印实例结果及end,再将res返回给func2
最终fucn1返回func2的返回值也就是res == a_func()
'''
携带参数的装饰器
def arg_func(sex): # sex 要传递的参数
def func1(base_func): # 被装饰的函数
def func2():
if sex == 'man':
print('this is boy')
if sex == 'woman':
print('this is girl')
base_func() # 执行被装饰的函数
return func2 # 将func2返回到func1
return func1 # 将func1 返回给arf_func
@arg_func(sex='man') # 传递的参数
def man():
print('man')
@arg_func(sex='woman')
def woman():
print('woman')
'''
执行流程
arg_func(sex='woman')(base_func)()
1.调用arg_func(sex=''man),内部返回了func1
2.fucn1携带被装饰的函数对象参数,返回了func
3.func内部处理逻辑和被装饰函数
'''
被装饰的函数携带参数
只需要在最内部函数传入参数即可
def func1(func): #外层函数接收被装饰的函数对象
def func2(x, y): # 内层函数接收被装饰的函数参数
x += 5
y += 5
return func(x, y) #调用被装饰函数,并且传参
return func2 #返回func2
@func1
def my_sum(a, b):
print(a + b)
my_sum(1, 2) #13
'''
虽然参数传递的是是1和2
但是经过func2()的时候 在内部进行了加法
最终到了fucn调用的时候传入的就是加过的值
'''
functools.wraps
装饰器在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变)
为了不影响,Python的functools包中提供了一个叫wraps的decorator来消除这样的副作用,如果要保留原有函数的名称和函数属性,可以使用对应方法
'''不使用functools'''
def func1(func):
def func2(x, y):
'''in func2'''
return func(x, y)
return func2
@func1
def my_sum(a, b):
'''in sum'''
print(a + b)
print(my_sum.__name__) # func2
print(my_sum.__doc__) # in func2
'''使用functools'''
#导包
import functools
def func1(func):
# 参数传入不被影响的被装饰函数,
# 操作相当于 func2.__name__ = my_sum.__name__
@functools.wraps(func)
def func2(x, y):
'''in func2'''
return func(x, y)
return func2
@func1
def my_sum(a, b):
'''in sum'''
print(a + b)
print(my_sum.__name__) # my_sum
print(my_sum.__doc__) # in sum
风月都好看,人间也浪漫.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)