侧边栏壁纸
博主头像
AngYi 博主等级

行动起来,活在当下

  • 累计撰写 68 篇文章
  • 累计创建 28 个标签
  • 累计收到 24 条评论

目 录CONTENT

文章目录

Python 装饰器

AngYi
2021-12-13 / 0 评论 / 0 点赞 / 278 阅读 / 0 字

python装饰器

装饰器用一句话解释,就是python闭包函数的一种语法糖,用来对函数进行辅助。

闭包本身是一个函数,其传入参数和返回值都是函数,有点切面编程的工厂设计模式的意思在里边感觉。

现在我们由浅入深来实现一个python装饰器的使用场景,并引出装饰器。

实现一个功能,记录查找1到100中奇数这个函数的执行时间。

1. 原始方法

import time

def print_odds():
    start_time = time.perf_counter()
    
    for i in range(100):
        if i % 2 != 0:
            print(i)
    end_time = time.perf_counter()
    
    print(f'运行总时间为{end_time - start_time}')


if __name__ == '__main__':
    print_odds()

缺点:函数主要逻辑不突出,辅助功能在函数内部占用地方,不利于维护。

2. 拆分主要函数和辅助函数

import time


def count_time(func):
    start_time = time.perf_counter()
    func()
    end_time = time.perf_counter()
    print(f'运行总时间为{end_time - start_time}')


def print_odds():
    for i in range(100):
        if i % 2 != 0:
            print(i)


if __name__ == '__main__':
    count_time(print_odds)

这样写的话主函数功能逻辑和辅助函数就能够解耦合了,但是对外调用的接口是辅助函数,不利用使用者使用。

3. 函数闭包

import time

# 闭包函数,本质是一个函数,传入和返回都是函数
def count_time(func):
    def improve_func():
        start_time = time.perf_counter()
        func()
        end_time = time.perf_counter()
        print(f'运行总时间为{end_time - start_time}')

    return improve_func


def print_odds():
    for i in range(100):
        if i % 2 != 0:
            print(i)


if __name__ == '__main__':
    print_odds = count_time(print_odds)
    print_odds()

这样做的话是不是就解决了上面第2点说的缺点,这里用到的就是闭包函数,这里要注意的点就是函数作为参数和返回的时候都是不加括号的。

但是这样写还是不够简洁,而且需要提前显式调用闭包函数对函数进行增强。

4. 装饰器

import time


def count_time(func):
    def improve_func():
        start_time = time.perf_counter()
        func()
        end_time = time.perf_counter()
        print(f'运行总时间为{end_time - start_time}')

    return improve_func


@count_time
def print_odds():
    for i in range(100):
        if i % 2 != 0:
            print(i)


if __name__ == '__main__':
    print_odds()

装饰器增强只增强一次,且在第一次调用时增强。

通用的装饰器

def general_wrapper(func):
  
  def wrapper(*args,**kwargs):
    ret  =  func(*args,**kwargs)
    return ret 
  
  return wrapper

5. 有参数的装饰器

import time


def count_time(param):
    print(param)
    def improve_func(func):
        def wrapper(*args,**kwargs):
            start_time = time.perf_counter()
            func(*args,**kwargs)
            end_time = time.perf_counter()
            print(f'运行总时间为{end_time - start_time}')
        return wrapper
    return improve_func


@count_time(123)
def print_odds(lim = 100):
    for i in range(lim):
        if i % 2 != 0:
            print(i)


if __name__ == '__main__':
    print_odds()
0

评论区