python装饰器
python装饰器文章目录python装饰器前言一、装饰器有什么作用?二、装饰器的使用1.函数式装饰器1. 循环 VS 列表推导式 VS map 效率比较2. 带有参数的装饰器2.类式装饰器的使用总结前言提示:在看python 一些包的源码时经常会看到 函数或者是类声明的上一行出现“@” 那么这个的作用是什么呢?:一、装饰器有什么作用?可以在不修改函数内部代码的情况下,修改函数的调用函数运行的日志
python装饰器
文章目录
前言
提示:在看python 一些包的源码时经常会看到 函数或者是类声明的上一行出现“@” 那么这个的作用是什么呢?:
一、装饰器有什么作用?
- 可以在不修改函数内部代码的情况下,修改函数的调用
- 函数运行的日志输出、计算时间……
- 增加函数或者时类的功能
二、装饰器的使用
1.函数式装饰器
代码如下:
data = [i for i in range(10 ** 7)]
def foo(func):
def getTime():
start = time.time()
func()
end = time.time()
print("运行时间 : ",end - start)
return getTime //返回一个callable
@foo
def main():
a = []
for i in data:
a.append(i * 2)
这段程序可用来计算函数的运行时间
装饰器可以将一个函数传入另一个函数,再通过另一个函数返回一个函数最后我们调用的时候使用的就是返回得到的这个函数。
1. 循环 VS 列表推导式 VS map 效率比较
@foo
def circulation():
a = []
for i in data:
a.append(i * 2)
@foo
def listMethod():
a = [i*2 for i in data]
@foo
def mapMethod():
# 需要转化成list 不然时间为0 ,map得到得到是一个可迭代的对象
a = list(map(lambda x:x * 2,data))
得到的结果 列表推导式 < for 循环 < map。(不过可能在不同的场景下的运行速率会有所不同,之前看到map方法的运行速率是排在中间的)
2. 带有参数的装饰器
在上面的例子中我们不好看出来输出的结果到底对应的是哪个,可以通过装饰器传参的形式实现。
# 装饰器部分的函数
def decoration(method):
def foo(func):
def getTime():
start = time.time()
func()
end = time.time()
print(f"{method}运行时间 : ",end - start)
return getTime
return foo
@decoration("circulation")
def circulation():
a = []
for i in data:
a.append(i * 2)
@decoration("listMethod")
def listMethod():
a = [i*2 for i in data]
@decoration("mapMethod")
def mapMethod():
# 需要转化成list 不然时间为0 ,map得到得到是一个可迭代的对象
a = list(map(lambda x:x * 2,data))
输出的结果:
2.类式装饰器的使用
代码如下(示例):
class Animal():
caration = "动物"
def __init__(self, func) -> None:
func.caration = self.caration
self.c1 = func
//magic方法可以让类也变成callable 即让类可以像函数一样被调用,可以用来修改类内的变量
def __call__(self, *args: Any, **kwds: Any) -> Any:
print("调用")
return self
@Animal
class Dogs():
def worfe():
print("I am a dog")
if __name__ == '__main__':
a = Dogs()
print(a.caration)
print(type(a))
输出的结果为:
可以通过第三个输出,可以推断出经过类装饰器后Dogs类变成了一个Animal类。
下面将增加Animal类中的方法
class Animal():
caration = "动物"
def __init__(self, func) -> None:
func.caration = self.caration
self.worfe = func.worfe
self.c1 = func
print("__call__")
def __call__(self, *args: Any, **kwds: Any) -> Any:
print("调用")
return self
@Animal
class Dogs():
def worfe():
print("I am a dog")
if __name__ == '__main__':
a = Dogs()
a.worfe()
输出结果应该为
__call__
调用
I am a dog
分析
观察输出结果我们知道我们声明得到的a其实就是
Animal
这个类中__call__
函数的返回值。
理解:a = Dogs() <=> a = Animal(Dogs)()
可以把这段进行替换发现结果是相同的。
总结
装饰器的主要的思想主要就是将一个func或者是class传递到另一个func或者class,并由此修改原函数或者类的一些功能。

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)