装饰器的概念
装饰器是程序开发过程中经常会用到的一个功能,用好装饰器,开发效率就会如虎添翼
装饰器的功能
引入日志,函数执行时间统计,执行前函数预备处理,执行后函数清理功能,权限校验等功能
学装饰器的前提
要想学好装饰器,需要了解什么是闭包
闭包的概念
在函数内部再定义一个函数,并且这个函数用到了外面函数的变量,那么将这个函数以及用到的一些变量称之为闭包
闭包的定义
def line_conf(a, b):
def line(x):
return a*x + b
return line
line1 = line_conf(1, 1)
print(line1(5))
当函数执行line_conf的时候,返回的是一个内层函数的地址.我们用line1接收line_conf返回的值,然后我们调用line1()函数,就等同于调用内层的line()函数,这就是一个闭包
装饰器的执行过程
装饰器的执行原理
# 这是一个闭包
def w1(fun):
def inner():
fun() # 指向了f1函数
return inner
# 这是一个普通函数
def f1():
print("这是f1函数")
# 将w1的返回值给f1
f1 = w1(f1)
# 此函数实际上执行的是inner()函数
f1()
装饰器的定义
def w1(fun):
def inner():
fun() # 指向了f1函数
return inner
@w1
def f1():
print("这是f1函数")
# 实际指向了inner函数
f1()
同一个函数被两个装饰器装饰时
如果一个函数被两个装饰器函数装饰,执行过程是从上至下,但实际装饰过程是从下至上
# 定义函数,完成包裹数据
def makeBold(fun):
print(“正在装饰1”)
def wrapped():
print(“—1—”)
return “” + fun() + “”
return wrapped
#定义函数,完成包裹数据
def makeItalic(fun):
print("正在装饰2")
def wrapped():
print("---2---")
return "<i>" + fun() + "</i>"
return wrapped
# 进行装饰
@makeBold # 相当于text3 = makeBold(text2)
@makeItalic # 相当于text2 = nameItalic(text3)
def text3():
print("---3---")
return "hello world!"
# 打印结果
ret = text3()
print(ret)
结果为
正在装饰2
正在装饰1
---1---
---2---
---3---
装饰器的分类
装饰无参数,无返回值的函数
def fun(functionName):
def fun_in():
print("这是fun_in函数")
functionName()
return fun_in
@fun
def f1():
print("这是f1函数!")
f1()
装饰有参数,无返回值的函数
def fun(functionName):
def fun_in(*args, **kwargs):
print("这是fun_in函数")
functionName(*args, **kwargs))
return fun_in
@fun
def f1(a, b):
print("%s%s" %(a, b))
f1(1, 2)
装饰无参数,有返回值的函数
def fun(functionName):
def fun_in():
print("这是fun_in函数")
ret = functionName()
return fun_in
@fun
def f1():
return "hello python!"
ret = f1() # 指向fun_in函数
print(ret)
装饰有参数,有返回值的函数(通用装饰器)
def fun(functionName):
def fun_in(*args, **kwargs):
print("这是fun_in函数")
ret = functionName(*args, **kwargs))
return fun_in
@fun
def f1(a, b):
return a + b
ret = f1(1, 2)
print(ret)
带参数的装饰器
带参数的装饰器的作用:能够在运行的过程中,起到不同的作用
# 需要一个三层函数来实现
def fun_arg(arg):
def fun(functionName):
def fun_in():
print("装饰器的参数是:%s" %(arg))
functionName()
return fun_in
return fun
@fun_arg("ha ha ha") # 装饰器带参数
def text():
print("---text---")
text()
类装饰器
call 魔法方法
class Test(object):
# __call__可以直接调用
def __call__(self):
print("---test---")
t = Test()
t()
结果为
---test---
类装饰器的用法
class Test(object):
def __init__(self, func):
print("初始化")
print("func name is %s" %func.__name__)
self.__func = func
def __call__(self):
print("装饰器的功能")
self.__func()
@Test # 相当于执行了test = Test(test)
def test():
print("---test--") # 敲完回车,自动开始装饰,出现以下信息
---初始化---
func name is test
结果为:
装饰器的功能
---test---