1. 本意: 不修改现有的函数时,需要对函数进行额外地扩展功能,需要使用装饰函数。
使用场景: 测试函数运行的时间, 在事务处理时的提交事务(数据库),打印日志。
如何定义装饰函数:
def loging(fn):
# 1.函数参数必须且只能为一个参数,代表某一个被修饰的函数名
# 2.定义一个包装函数
# 3.包装函数名可以任一命名,参数必须是*args, **kwargs
def wrapper(*args, **kwargs):
# 4.编写扩展的功能语句
print(‘———’)
# 5.调用被修饰的函数
#调用时,必须传入 wrapper包装函数中的两个参数:*args, **kwargs
return fn(*args, **kwargs) #返回结果,如果想在函数调用后扩展功能,修改如:
# result = fn(*args, **kwargs)
# 6.被修饰函数调用后的 扩展功能
# print(‘*******’)
# return result
return wrapper
# 7最后,为装饰函数返回 包装函数名
2.如何使用修饰函数:
在某一个现有函数上一行: @修饰函数名,如:
@loging
def add(x, y):
return x + y
add(10, 20)
3.被修饰的函数执行的过程:
1.调用被修饰的函数, 在Python解析器,发现有一个装饰函数,
停止对被修饰函数的调用,转到2步。
2.调用装饰函数,同时传一个被装饰的函数名,发现装饰函数返回了
一个其内部包装(wrapper)函数,转入第3步。
3.调用装饰函数的包装函数,同时传入被装饰函数中的实际参数,
在包装函数中调用被装饰的函数,在调用它的前后可以扩展自己的功能。
最后 将 被装饰函数返回的结果 返回给调用的地方,即转给第1步的调用位置。
4.装饰函数使用场景:
1. 验证数据的有效性(salary < 1000 , 参数列表中必须存在id=‘101’)
2. 测试功能函数的运行时间(测性能: 内存占用情况 ,CPU使用情况)
3. 数据库操作过程中事务的处理
定义装饰函数:
1) 定义装饰函数,同时函数参数接收一个函数名(被装饰的函数名), 返回一个其内部的包装函数(内部: 可以调用被装饰的函数)
def decorate(fn):
return wrapper 内部的包装函数名
2) 定义装饰函数中的包装函数, 函数的参数必须是*args, **kwargs
一般情况下,返回被装饰函数执行的结果
def decorate(fn):
#执行扩展功能
def wrapper(*args, **kwargs)
return fn(*args, **kwargs)
‘’’
result = fn(*args, **kwargs)
调用功能后的扩展功能
return result
‘’’
return wrapper
使用装饰函数: 在某一函数的上一行,使用@装饰函数名
@decorate
def addSalary(salary):
print(‘salary add success!’)
网友评论