当前位置: 首页 > 图灵资讯 > 行业资讯> python中的装饰器的使用实战

python中的装饰器的使用实战

发布时间:2025-10-07 17:41:29

1、了解装饰

装饰器的目的是在另一个函数中嵌入一个函数进行重复使用,不改变其结构,增加函数的使用方式,但不需要写太多冗余代码;

装饰本质上是Python函数,可以在不做任何代码变化的情况下增加其他函数的额外功能,装饰的返回值也是函数对象。

常用功能:1。引入日志;2.函数执行时间统计;3.执行函数前的准备;4.执行函数后的清理功能;5.权限验证;6.缓存

2、实现原理和一般写法

我们可以从一个简单的装饰器中推断出一个通用的装饰写作方法,简单地记录函数的运行时间

importtime

deftimer(func):
'''
记录装饰器的操作时间
:paramfunc:方法
:return:函数对象
'''
defdeco(*args,**kwargs):
startTime=time.time()
f=func(*args,**kwargs)
endTime=time.time()
msecs=(endTime-startTime)*1000
print("timeis%dms"%msecs)
returnf#如果func值得返回,则需要在此return返回。否则,默认返回值为none,一般默认返回

returndeco


@timer
deftest(parameter):
print("testisrunning!")
time.sleep(1)
return"Returnedvalue"#该函数具有返回值,因此需要在装饰器的deco方法中写入返回值


t=test('aa')
print(t)

这是一种非常简单的装饰,可以记录时间,从而推导出一种通用的装饰写作方法:

deffunc_name(func):#装饰函数名称的自定义
defdeco(*args,**kwargs):#原封不动地传递所有参数
print("在此分割线上写下函数运行前的操作")
#-----------分割线-----------
f=func(*args,**kwargs)
#-----------分割线-----------
print("在这条分割线之后,return之前,编写函数运行后的操作")
returnf#如果func值得返回,则需要在此return返回。否则,默认返回值为none,一般默认返回

returndeco


@func_name
deftest(parameter):#8
print("testisrunning!")
time.sleep(1)
return"Returnedvalue"#该函数具有返回值,因此需要在装饰器的deco方法中写入返回值


t=test('aa')
print(t)

ok 装饰可以在这里完成。一般来说,它可以满足需求。在互联网上阅读这么多原则是浪费时间。我更喜欢实用型。我真的不喜欢罗嗦那么多。我只是这么做。

当然,在开发过程中, 我们可能会遇到一些特殊情况,如参数问题

1、赋予装饰函数代参数(通用)

2、拆分计算执行函数的参数(如1000w的数据,拆分为100份执行等)(定制)

然后按顺序来

1、写代参数的装饰器

deflogging(level):
defwrapper(func):
definner_wrapper(*args,**kwargs):
print("[{level}]:enterfunction{func}()".format(level=level,func=func.__name__))
returnfunc(*args,**kwargs)
returninner_wrapper
returnwrapper

@logging(level='INFO')
defsay(something):
print("say{}!".format(something))

#假如没有使用@语法,就等于
#say=logging(level='INFO')(say)

@logging(level='DEBUG')
defdo(something):
print("do{}...".format(something))

if__name__='__main__':
say('hello')
do("mywork")

发现:在上面的通用模板上又盖了一层!!,然后得到里面的参数! so easy!!!

2、写一个参数拆分的装饰器,稍微定制一下,不能像上面那样通用。举个例子 栗子:

deffunc_name(func):#装饰函数名称的自定义
defdeco(*args,**kwargs):#原封不动地传递所有参数
print(args[0])
f_list=[]
foriinrange(0,args[0],100000):
print(i)
f_list.append(func(i))
#f_list#这里应该按照既定的规则继续拼接这个结果。如果是写文件、入库等操作,不需要returnn
returnf_list#如果这里有返回值,应该是

returndeco

@func_name
deftest(parameter):#8
print("testisrunning!")
time.sleep(1)
return"Returnedvalue"#该函数具有返回值,因此需要在装饰器的deco方法中写入返回值


t=test(1000000)
print(t)

可以看出,这种定制略高,不通用,但我们实现了我们的需求,所以我们应该理解和学习如何使用它!!!

可以看出,这种定制略高,不通用,但我们实现了我们的需求,所以我们应该理解和学习如何使用它!!!

下面介绍一下基于类实现的装饰器。问题来了。我是实战派,不需要类装饰器。所以,做个大盗,以后用了就不会瞎找了!!!

装饰函数实际上是一种接口约束。它必须接受一个callable对象作为参数,然后返回一个callable对象。在python中,callable对象通常是函数,但也有例外。只要对象重新加载__call__()方法,那么这个对象就是callable。

classTest():
def__call__(self):
print'callme!'
t=Test()
t()#callme

像__call__这种前后划线的方法在Python中被称为内置方法,有时也被称为魔法方法。重载这些魔法方法通常会改变对象的内部行为。上面的例子使一个类对象有被调用的行为。

回到装饰器的概念,装饰器需要接受一个callable对象,并返回一个callable对象(不太严格,详见后面)。

所以也有可能通过类来实现。我们可以让类的构造函数__init__()接受函数,然后重载__call__()并返回一个函数,也可以达到装饰函数的效果。

classlogging(object):
def__init__(self,func):
self.func=func

def__call__(self,*args,**kwargs):
print"[DEBUG]:enterfunction{func}()".format(
func=self.func.__name__)
returnself.func(*args,**kwargs)
@logging
defsay(something):
print"say{}!".format(something)

带参数的类装饰器

如果需要以类形式实现带参数的装饰,则会比前面的例子稍微复杂一些。那么,在构造函数中接受的不是函数,而是传入的参数。通过类保存这些参数。

然后重载___call__方法是接受函数并返回函数。

classlogging(object):
def__init__(self,level='INFO'):
self.level=level

def__call__(self,func):#接受函数
defwrapper(*args,**kwargs):
print"[{level}]:enterfunction{func}()".format(
level=self.level,
func=func.__name__)
func(*args,**kwargs)
returnwrapper#返回函数

@logging(level='INFO')
defsay(something):
print"say{}!".format(something)

相关文章

python中的装饰器的使用实战

python中的装饰器的使用实战

2025-10-07
python中事件处理的方法

python中事件处理的方法

2025-10-07
FuckIt.py库让你的代码从此远离bug

FuckIt.py库让你的代码从此远离bug

2025-10-07
鲜为人知的python位运算

鲜为人知的python位运算

2025-10-07
实例讲解join方法的使用

实例讲解join方法的使用

2025-10-07
Python如何实现定时发送qq消息

Python如何实现定时发送qq消息

2025-10-07