python函数装饰器篇
python装饰器专栏
1.了解装饰器
1. 函数装饰器,函数的简单功能的增强
2. 类装饰器,复杂功能的增强
2.闭包
1.简单讲就是在函数内在嵌套一个函数,就变成了闭包
// 闭包的结构
def outer():
def inter():
print("这是内部函数")
return inter
// 闭包传参
def outer(x):
def inter(y):
print(x)
return inter
outer(1)(6)
@语法糖
1. @标识符:在函数上面加上@另一个函数名,的作用是将这个修饰符下面的函数作为该修饰符函数的参数传入
例子-原函数
def my_func1(x, y):
print(x + y)
time.sleep(1)
return x + y
def my_func2(x, y):
print(x * y)
time.sleep(1)
return x * y
def my_func3(x, y):
print(x - y)
time.sleep(1)
return x - y
my_func3(500, 300)
my_func2(500, 300)
my_func1(500, 300)
需求: 统计每个函数的运行时间
第一种解法: #1 在每个函数体运行之前,以及运行之后+统计时间
'''第一种解法'''
def my_func1(x, y):
# 1 解法1
t1 = time.time()
print(x + y)
time.sleep(1)
# 1 解法1
t2 = time.time()
print("执行时间==", t2 - t1)
return x + y
def my_func2(x, y):
# 1 解法1
t1 = time.time()
print(x * y)
time.sleep(1)
# 1 解法1
t2 = time.time()
print("执行时间==", t2 - t1)
return x * y
def my_func3(x, y):
# 1 解法1
t1 = time.time()
print(x - y)
time.sleep(1)
# 1 解法1
t2 = time.time()
print("执行时间==", t2 - t1)
return x - y
my_func3(500, 300)
my_func2(500, 300)
my_func1(500, 300)
第二种解法: :函数装饰器
说明: 在使用装饰器前,需要了解知道
1. func 这个是指向的地址值
2. func() 加上括号才是真正实行函数
解法如下
'''
第二种解法:函数装饰器
优点:
1. 可以不修改原函数(修改原函数容易出问题)
2. 使用装饰器增强函数功能,打个补丁过去 即装饰器
装饰器原理:
1. 语法糖执行fucs,将函数名字传入
2. 执行return wrapper
3. 执行内部函数wrapper(*args, **kwargs):
4. 然后执行传入过来的fucn()
'''
def fucs(func):
def wrapper(*args, **kwargs):
t1 = time.time()
# 执行传过来的函数
res = func(*args, *kwargs)
t2 = time.time()
print(t2 - t1)
return res
# 返回
return wrapper
@fucs
def my_func1(x, y):
print(x + y)
time.sleep(1)
return x + y
@fucs
def my_func2(x, y):
print(x * y)
time.sleep(1)
return x * y
@fucs
def my_func3(x, y):
print(x - y)
time.sleep(1)
return x - y
my_func3(500, 300)
my_func2(500, 300)
my_func1(500, 300)
以上看似没有改变函数名字实际我来看下
# @fucs
def my_func3(x, y):
print(x - y)
time.sleep(1)
return x - y
print(my_func3.__name__)
my_func3(500, 300)
print(my_func3.__name__)
'''
没有加装饰器时输出显示的原函数名字
'''
my_func3
200
my_func3
'''
加上装饰器显示的是装饰器内部名字
'''
@fucs
def my_func3(x, y):
print(x - y)
time.sleep(1)
return x - y
print(my_func3.__name__)
my_func3(500, 300)
print(my_func3.__name__)
# 输出结果
wrapper
200
1.0079624652862549
wrapper
备注: 以上仍然是悄悄的改变了函数的名字,装饰器的原则是不改变任何原函数,故需要加上
解决方案:加上系统的不修改原函数名字的装饰器
from functools import wraps
def fucs(func):
# 加上系统不修改原函数的装饰器
@wraps(func)
def wrapper(*args, **kwargs):
t1 = time.time()
# 执行传过来的函数
res = func(*args, *kwargs)
t2 = time.time()
print(t2 - t1)
return res
# 返回
return wrapper
# 输出结果:(保留了原函数的名字)
my_func3
200
1.002612829208374
my_func3