本文小编为大家详细介绍“Python装饰器怎么正确使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Python装饰器怎么正确使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
Python 3.6.8
什么是装饰器
要理解装饰器之前,我们需要了解什么是闭包函数。
闭包函数
我们简单写个demo
,再解释一下什么是闭包函数。
def exterFunc(x): def innerFunc(y): return x * y return innerFunc def main() -> None: f = exterFunc(6) result = f(5) print(result) if __name__ == '__main__': main()
可以看到,上述代码所示,所谓的闭包函数是指: 闭包函数是指在函数中再定义函数,内部函数可以访问外部的变量,在外部函数中,将内部函数作为返回值返回。
可以看到上述例子中,我们定义了exterFunc
的函数,它将接收一个形参x
,在exterFunc
函数中又中定义了innerFunc
,它也接收一个形参y
, 在innerFunc
函数中,返回x * y
,没错,内部函数可以访问外部函数传入的变量,最后将exterFunc
作为返回值返回,这就是闭包函数。
最简单的装饰器
装饰器是一种很特殊的函数,可以接收函数作为形参,且返回一个新的函数,在我们上一篇介绍生成器的时候,还记得我们使用memory_profiler
库来打印函数的内存运行情况么? 这就是用的装饰器。
我们可以写个最简单的例子,来阐述一下python
装饰器,即:
def foo(func): def wrapper(): print("装饰器开始运行了") func() print("装饰器结束运行了") return wrapper @foo def sayHello(): print("hello pdudo in juejin") def main() -> None: sayHello() if __name__ == '__main__': main()
上面代码,我们定义了一个装饰器foo
,foo
需要传入一个函数, foo
内部有一个函数wrapper
。这样的函数中包函数,我们将其称之为闭包函数,后面会介绍闭包函数。言归正传,在wrapper
函数中,我们可以在运行func
函数的时候,再其执行前后语句。
为什么需要装饰器
要解释这个问题,我们可以看来了解下,装饰器解决了一些什么问题:
说了那么多,我们来列举一个最简单的例子,利用装饰器打印一下函数的运行时间。
import time def getExecTimers(func): def wrapper(): startTimes = time.time() func() endTimes = time.time() print("函数运行时间: " , endTimes - startTimes ,"s") return wrapper @getExecTimers def testFunc(): print("开始执行函数") time.sleep(5) print("函数执行结束") def main() -> None: testFunc() if __name__ == '__main__': main()
这个装饰器,会记录函数的运行时间。可以看到,我们为这个函数增加了一个附属功能,但是又没有修改到原始函数。
上述案例,应该可以证明为什么需要使用装饰器了。
装饰器用法
上述我们讨论了最简单的装饰器写法,并且写了一个小功能,即打印函数的运行时间。接下来,我们要看下装饰器的其他写法。
不是用语法糖调用
还记得上面我们调用装饰器,是使用的@
+装饰器名称么? 其实这是python
的语法糖,如果不是用语法糖的话,应该是这样来使用的:
def foo(func): def wrapper(): print("装饰器开始运行了") func() print("装饰器结束运行了") return wrapper def sayHello(): print("hello pdudo in juejin") def main() -> None: f1 = sayHello f2 = foo(f1) f2() if __name__ == '__main__': main()
f1 = sayHello f2 = foo(f1) f2()
带参数的装饰器
这里要做一个铺垫,在python
中,有2个特殊的变量,分别为*args
和**kwargs
,都是用来处理不定量参数的,分别代表的含义为:
def foo(func): def wrapper(*args,**kwargs): print("装饰器开始运行了") print("装饰器捕获到的参数: " ,args,**kwargs) func(*args,**kwargs) print("装饰器结束运行了") return wrapper @foo def sayHello(a,b,c,dicts): print("传入的参数: " , a,b,c) print("传入的参数: " , dicts) def main() -> None: sayHello(1,2,3,{"name":"juejin"}) if __name__ == '__main__': main()
在装饰器中,若我们要给函数传递参数,是需要先将参数传递给装饰器,而在装饰器中接收后再进行传递的,所以代码才会是这样的:
def foo(func): def wrapper(*args,**kwargs): print("装饰器开始运行了") print("装饰器捕获到的参数: " ,args,**kwargs) func(*args,**kwargs) print("装饰器结束运行了")
首先,我们在做传递调用的时候,wrapper
应该调用形参来接收,接收后,再进行传递给函数func
。
读到这里,这篇“Python装饰器怎么正确使用”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程之家行业资讯频道。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。