python装饰器的使用
装饰器就是给已有函数增加额外功能的函数,它本质上就是一个闭包函数。
0.装饰器的功能特点:
-
不修改已有函数的源代码
-
不修改已有函数的调用方式
-
给已有函数增加额外的功能
1.装饰器的简单使用(装饰带无参数的函数)
# 装饰器函数的简单演示
def func_main(func):
def inner():
# 函数前可增加额外的功能
print("函数前可增加额外的功能!")
func()
# 函数后可增加额外的功能
print("函数后可增加额外的功能!")
return inner
# @func_main表示语法糖,代表 func1 = func_main(func1) 也代表 inner + func1对象
@func_main
def func1():
print("我是func1函数")
func1() # 调用func1函数
运行结果:
函数前可增加额外的功能!
我是func1函数
函数后可增加额外的功能!
装饰器内部参数传递过程:
2. 装饰带有参数的函数
# 添加输出日志的功能
def logging(func):
def inner(num1, num2):
print("--正在努力计算--")
func(num1, num2)
return inner
# 使用装饰器装饰函数
@logging
def sum_num(a, b):
result = a + b
print(result)
sum_num(1, 2)
运行结果:
--正在努力计算--
3
3. 装饰带有返回值的函数
# 添加输出日志的功能
def logging(func):
def inner(num1, num2):
print("--正在努力计算--")
result = func(num1, num2)
return result
return inner
# 使用装饰器装饰函数
@logging
def sum_num(a, b):
result = a + b
return result
result = sum_num(1, 2)
print(result)
运行结果:
--正在努力计算--
3
装饰器内部参数传递过程:
4. 装饰带有不定长参数的函数
# 添加输出日志的功能
def logging(fn):
def inner(*args, **kwargs):
print("--正在努力计算--")
fn(*args, **kwargs)
return inner
# 使用语法糖装饰函数
@logging
def sum_num(*args, **kwargs):
result = 0
for value in args:
result += value
for value in kwargs.values():
result += value
print(result)
sum_num(1, 2, a=10)
运行结果:
--正在努力计算--
13
5. 通用装饰器
# 添加输出日志的功能
def logging(fn):
def inner(*args, **kwargs):
print("--正在努力计算--")
result = fn(*args, **kwargs)
return result
return inner
# 使用语法糖装饰函数
@logging
def sum_num(*args, **kwargs):
result = 0
for value in args:
result += value
for value in kwargs.values():
result += value
return result
@logging
def subtraction(a, b):
result = a - b
print(result)
result = sum_num(1, 2, a=10)
print(result)
subtraction(4, 2)
计算结果:
--正在努力计算--
13
--正在努力计算--
2
6. 小结
- 通用装饰器的语法格式:
# 通用装饰器
def logging(func):
def inner(*args, **kwargs):
print("--正在努力计算--")
result = func(*args, **kwargs)
return result
return inner
7、带参数的装饰器
- 装饰器使用语法糖添加时,只能给装饰器函数传递一个参数,这个参数就是被装饰的函数对象
- 如果想给装饰器添加参数,要么不使用语法糖,要么再嵌套一层闭包。
- 提示:在开发中一个函数可以添加多个装饰器
import time
# 先写一个通用装饰器
# 再在装饰器中添加一个参数, 标明计算时睡眠几秒
def compute(symbol, t):
def func_out(func):
def func_in(*args, **kwargs):
if symbol == '+':
print('正在努力进行加法计算...')
elif symbol == '-':
print('正在努力进行减法计算...')
else:
print('符号输入有误')
# 等待计算的时间
time.sleep(t)
result = func(*args, **kwargs)
return result
return func_in
return func_out
@compute('+', 0.5)
# @compute('+') ==> sum1 = compute('+')(sum1) ==>func_out(sum1) + symbol
# ==>func_in + 原始的sum1对象 + symbol 参数
# 如果有两个参数
# @compute('+', 0.5) ==> sum1 = compute('+', 0.5)(sum1)
# ==> func_out(sum1) + symbol + t
# ==> func_in + 原始的sum1对象 + symbol + t
def sum1(num1, num2):
return num1 + num2
@compute('-', 0.5)
def sub(num1, num2):
return num1 - num2
print(sum1(4, 5))
print(sub(5, 2))
计算结果:
正在努力进行加法计算...
9
正在努力进行减法计算...
3
8. 应用实例----装饰器实现已有函数执行时间的统计
import time
# 装饰器函数
def get_time(func):
def inner(*args, **kwargs):
begin = time.time()
func(*args, **kwargs)
end = time.time()
print("函数执行花费%f" % (end - begin))
return inner
@get_time
def func_sum(num, sum_it=0):
"""求0-num的和"""
for i in range(num + 1):
sum_it += i
print(sum_it)
func_sum(1000000, sum_it=0)
计算结果:
500000500000
函数执行花费0.067817