装饰器回顾
我们来认识一下装饰器,装饰器本身就是一个函数,他的存在为了给其他函数增加功能。如果说在一个项目中需要给特定的一些函数执行一些方法,而不改变原来的方法。因为在项目中有“开放封闭”原则,这个原则大意思就是在编写函数是,不能修改原来的函数。之前编写的这个函数可能被多个函数所调用,如果修改的话,需要大规模的修改超级复杂,而且包含大量的重复代码,这并不是我们所希望的。这就是装饰器可以解决的问题。
在正式学习装饰器之前,需要先来学习三个概念
1,作用域
2,高阶函数;函数名可以作为参数,函数名可以作为返回值
3,闭包:有一个内部函数,在内部函数内有外部函数的变量引用
这三个概念,只有闭包大家可能不太懂,下面我们通过例子来说一下闭包
def outer([y]):
x=10
def inner():#inner就是内部函数
print(x)#外部环境的一个变量;在这里如果引用y也属于外部环境的变量
return inner#结论:内部函数inner就是一个闭包
outer()
在原来的时候,我们不能在函数outer执行结束后再去拿到x的值,但是正是闭包的因素,使我们可以拿到x的值。
下面我们来学习装饰器
def foo():
print('foo...')
def show_time(fun):#这里show_time是装饰器
def inner():
fun()
print('实现额外的功能')
return inner
foo=show_time(foo)
# 还是使用原来的调用方式
foo()
这就是一个装饰器的例子,它的执行过程为,首先把定义的函数存放到内存中,等到执行foo=show_time(foo)时,执行等号右边的,把函数名作为一个参数传进去它的返回值是一个内部的函数,在这个内部函数中执行了foo函数,把额外的功能放到inner中来实现。返回的是一个函数名赋给foo这样就不改变原来的调用方式。
在Python中提供了@符来表示;这种写法是等价的
@show_time # foo=show_time(foo)
def foo():
print('foo...')
在以上只是实现了封闭原则,而且也能给函数增加功能,但是不能实现对于特定的函数实现特定的操作,比如A方法需要记录日志,而B方法不需要就不容易处理了。我们可以通过传标志信息来标明那些函数需要记录日志信息。下面引入两层的内部函数
def log(flag=''):
def show_time(f):
def inner():
f()
print('end')
if flag=='true':
print('需要记录日志信息')
return inner
return show_time
@log('true')
def foo():
print('foo...')
foo()
在这里首先加载log函数到内存,foo的函数调用和上面是一样的,但是大家可能有一点不理解就是@log('true')#log('true')=show_time这一句。在log函数中传递了一个默认参数,在log('true')中返回的是show_time就相等于@show_time
领取专属 10元无门槛券
私享最新 技术干货