装饰器decorator
装饰器,在设计模式中有一种模式叫做装饰器模式,虽说不完全是设计模式中的那个,
但是其思路是一致的。目的都是需要添加功能,但是又不希望更改原来的代码。
比如我已经有一个函数do_something()
,然后我希望添加一些功能,但是又不应该
直接去更改这个函数的代码,我们就可以通过装饰器的方式,在前后进行添加,并且
将这个函数包裹起来。由于python的函数式特性,我们可以很轻松的做到这一点,
因为其函数是first class的,也就是说函数可以作为参数等传递。
其实这个概念是非常简单的,如果说有一些麻烦的地方就是python的装饰器语法,装饰器
语法其实只是一个语法糖,不过因为这个语法糖使得装饰器不那么直观了(但是要是没有
装饰器语法,我们也就不需要把装饰器拿出来说啦)
函数作为参数
在python中,函数可以作为参数进行传递:
def call_a_func(func):
func()
def hello():
print("hello")
call_a_func(hello)
这里我们将hello传入了call_a_func
函数,这个函数将传入的参数进行调用,也就是其
接收的参数是一个函数,而他调用了这个函数,相信这个例子足以让人理解函数作为参数了。
装饰器语法
装饰器语法,形式为:
@decorator
def hello():
pass
这里的decorator是装饰器的名字,也就是另外一个函数,hello是一个函数。
注意,这里的@decorator 相当于 hello = decorator(hello)
其实这句话才是我写这个博客的重点,因为只要记住这个用法,别的讲解都不需要了。
装饰器,相当于将原函数作为参数,然后将装饰器的返回结果代替原函数,有了这个结果,
我们其实就可以随心所欲使用装饰器了。
在实际使用当中,有一些技巧,比如:
def deco(func):
def _deco():
print("pre")
func()
print("post")
return _deco
@deco
def hello():
pass
这里我们相当于使用了hello = deco(hello)
,最后使得新的hello为deco内部定义的_deco函数,
这个函数调用了原hello并且在前后增加了功能,为什么不直接在前后做一些功能然后返回原来
的hello呢?这是因为这样的效果只完成一次,如果返回原hello,只在第一次调用deco的时候
会有前后添加功能的效果,等到deco返回之后,以后的调用就只使用了hello了。所以,装饰器
并非每一次调用都会进入hello = deco(hello)
,而是只进行一次