Python装饰器
- Python装饰器
- 前言
- 函数作为变量进行传递
- 函数做为参数进行传递
- 函数可以作为一个返回值
- 总结
- 啥是装饰器
- 不使用装饰器,代码这样写的
- 总结
- 装饰器
- 总结
- 装饰器运行过程说明
Python装饰器
前言
- 在学习装饰器之前,我们先来了解一下,Python中的函数可以像普通变量一样当做参数传递给另外一个函数
函数作为变量进行传递
请认真看代码里的每一行注释,认真理解
#! /usr/bin/python3
# @Author : 无涯
def hello():
print("执行hello函数")
# 打印hello的内存地址
print("hello的内存地址:", hello)
# 将hello赋值给word
word = hello
# word和hello的内存地址一样的
print("word的内存地址:", word)
# 再调用方法
word()
# 运行结果
hello的内存地址: <function hello at 0x000001FA8BCAC1E0>
word的内存地址: <function hello at 0x000001FA8BCAC1E0>
执行hello函数
函数做为参数进行传递
- 请认真看代码里的每一行注释,认真理解
"""
函数的传递
"""
def hello():
print("执行hello函数")
# 定义一个形参name
def word(name):
name()
print("执行word函数")
# 将hello以变量的形式传给name,然后name()调用hello的方法
word(hello)
# 运行结果
执行hello函数
执行word函数
函数可以作为一个返回值
- 请认真看代码里的每一行注释,认真理解
def hello():
print("执行hello函数")
# 定义一个形参name
def word(name):
print("执行word函数")
print("hello内存地址:", name)
return name
# hello传给name,再打印hello内存地址
result = word(hello)
print(result)
总结
- 理解以上三个案例后,我们来正式学习什么是装饰器
啥是装饰器
- 装饰器本质一个python函数/类
- 作用:
- 可以让其它函数或类不改动代码的前提下增加额外功能
- 不改变代码运行方式
- 装饰器返回值也是一个函数/类
不使用装饰器,代码这样写的
- 没使用装饰器之前,你可能是封装一个日志打印方法,然后是这样的
#! /usr/bin/python3
# @Author : 无涯
import logging
import time
"""
获取函数名:__name__
需求:
1/每个函数执行的时候打印日志
2/函数运行时间
"""
# 封装日志打印
def log_fun(fun):
start_time = time.time() # 获取函数执行之前的时间
fun()
end_time = time.time()
run_time = end_time - start_time
logging.warning("执行{0}函数, 运行时间: {1:.2}".format(fun.__name__, run_time))
def fun1():
time.sleep(2)
print("执行函数1")
def fun2():
time.sleep(3)
print("执行函数2")
log_fun(fun1)
log_fun(fun2)
总结
- 虽然功能实现了,但调用代码不是调用真正业务逻辑fun1和fun2,而是换成了log_fun,破坏了原有代码结构
- 每次要把fun1等方法传给log_fun
- 如何更加完美解决这个问题,就要用到装饰器
装饰器
- 认真理解注释内容
import logging
import time
"""装饰器"""
def log(fun): # fun参数即分别为原始函数:fun1/fun2
"""log方法返回值是wrapper函数的返回值, 即也是原始函数的返回值"""
def wrapper():
"""wrapper方法的返回值就是原始函数的返回值"""
start_time = time.time()
result = fun() #执行原始函数的过程
end_time = time.time()
run_time = end_time - start_time
logging.warning("执行{0}函数, 运行时间: {1:.2}".format(fun.__name__, run_time))
return result # 返回原始函数(fun1/fun2)的返回值
return wrapper # 装饰器固定语法, 返回函数
"""装饰器运行过程
1、调用fun()时,先执行@log:相当于执行了语句 fun1 = log(fun1)
2、fun1() 调用方式结构不变,实际是执行装饰器里wrapper方法,即运行:wrapper()
"""
def fun1():
time.sleep(3)
print("执行函数1")
return "函数1返回值"
def fun2():
time.sleep(2)
print("执行函数2")
return "函数2返回值"
result1 = fun1()
result2 = fun2()
print(result1, result2)
# 运行结果
WARNING:root:执行fun1函数
WARNING:root:执行fun2函数
执行函数1
执行函数2
函数1返回值 函数2返回值
总结
- 没有改动原始代码
- 调用方式没改变
- 新增了新的功能
装饰器运行过程说明
"""装饰器运行过程
1、调用fun()时,先执行@log:相当于执行了语句 fun1 = log(fun1)
2、fun1() 调用方式结构不变,实际是执行装饰器里wrapper方法
"""
如果想学习软件测试,就快加入:893694563,群内学软件测试,分享技术和学习资料,陪你一起成长和学习。