【python】装饰器基础

  • 什么是装饰器?
    • 装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
  • 为何要用装饰器?
    • 开放封闭原则:
      • 开放:指的是对拓展功能是开放的
      • 封闭:指的是对修改源代码是封闭的
  • 装饰器基础知识
    • 作用域
    • 高阶函数:
      • 满足两个条件之一就叫高阶函数:
      • 1、函数名可以作为参数输入
      • 2、函数名可以作为返回值
    • 闭包:
      • 如果在一个内部函数里,对在外部作用域(但不是全局作用域)的变量进行引用,那么内部函数就认为是闭包
  • 如何用?
#在不改变foo函数及不改变调用方式的情况下,添加统计运行时间的功能
def foo():
    print('hello world!!!')
    time.sleep(2)
foo()

#解决方案一:失败,修改了源代码
import time
def foo():
    start = time.time()
    print('hello world!!!')
    time.sleep(2)
    end = time.time()
    print(end - start)
foo()

#解决方案二:失败,修改了调用方式
import time
def foo():
    start = time.time()
    print('hello world!!!')
    time.sleep(2)
    end = time.time()
    print(end - start)

def show_time():
    start = time.time()
    foo()
    end = time.time()
    print(end - start)
show_time()

#解决方案三:失败,将show_time函数做的跟装饰一样,以假乱真。但是每次都需要重新赋值
import time
def show_time(f):
    def inner():
        start = time.time()
        f()
        end = time.time()
        print('speed %s'%(end-start))
    return inner


def foo():
    print('hello world!!!')
    time.sleep(2)

foo = show_time(foo)   #foo指向show_time函数的内存地址
foo()

#解决方案四:语法糖
# 缺点,不同的功能函数,参数可能不一致
import time
def show_time(f):
    def inner():
        start = time.time()
        f()
        end = time.time()
        print('speed %s'%(end-start))
    return inner

@show_time    #foo = show_time(foo)
def foo():
    print('hello world!!!')
    time.sleep(2)
foo()

# 5,最终版
import time
def show_time(f):
    def inner(*args,**kwargs):
        start = time.time()
        f(*args,**kwargs)
        end = time.time()
        print('speed %s'%(end-start))
    return inner

@show_time    #foo = show_time(foo)
def foo(id):
    print('hello world!!!',id)
    time.sleep(2)
def fun01(id,name)
    print(f'{id},{name}')

foo(102)
fun01(1,'xwl')
posted @ 2022-10-24 22:27  Tony_xiao  阅读(26)  评论(0编辑  收藏  举报