0
点赞
收藏
分享

微信扫一扫

Python装饰器从理解到真正掌握,分享我今天整理的笔记



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()
"""

@log
def fun1():
time.sleep(3)
print("执行函数1")
return "函数1返回值"

@log
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,群内学软件测试,分享技术和学习资料,陪你一起成长和学习。



举报

相关推荐

0 条评论