有勇气的牛排博客
☰

Python 装饰器模式 Decorate Patter


知止自律打卡-微信小程序APP
一款微信自律打卡小程序,支持自定义打卡项目、习惯记录、项目日记、专注计时与数据统计。自律打卡、学习打卡、读书打卡、健身打卡、运动打卡、减肥打卡、戒色打卡、养生打卡、戒烟、戒酒、戒熬夜等多种场景。万能打卡模板自由创建。可自定义每日打卡目标,记录习惯连续天数,可视化追踪成长进度。
了解产品详情 →
微信搜索「知止自律打卡」
知止自律打卡微信小程序

Python 装饰器模式 Decorate Patter

1 前言

1.1 定义

如果装饰器有多个,则从下往上依次执行。

1.1.1 设计模式角度

装饰器模式是一种结构型设计模式,允许在不修改原始类代码的前提下,动态地扩展对象的功能。

1.1.2 Python 角度

Python装饰器是一个接收函数/类作为参数,返回一个增强后的函数/类的高阶函数。

1.2 优缺点

优点:

缺点:

2 基本写法

# -*- coding: utf-8 -*-
def my_decorate(func):
    def wrapper(*args, **kwargs):
        print("开始执行")
        result = func(*args, **kwargs)
        print("结束执行")
        return result

    return wrapper

@my_decorate
def greet(name):
    print(f"你好:{name}")

greet("有勇气的牛排")

# 等价写法
# greet = my_decorate(greet)
# greet("有勇气的牛排")

image.png

3 常见场景

3.1 权限校验

# -*- coding: utf-8 -*-
def require_admin(func):
    def wrapper(user_role, user_id, *args, **kwargs):
        if user_role != 'admin':
            print('无权限')
        else:
            return func(user_role, user_id, *args, **kwargs)

    return wrapper


@require_admin
def get_user_info(user_role, user_id):
    print('正在获取用户信息')


get_user_info("admin", 1)
get_user_info("guest", 2)

3.2 耗时统计

# -*- coding: utf-8 -*-
import time

def func_run_time(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print("函数运行时间:%s" % (end_time - start_time))
        return result

    return wrapper

@func_run_time
def test():
    time.sleep(1)

test()

image.png

3.3 类装饰器

类也可以作为装饰器使用,可用于更复杂的状态维护。

这里需要使用到魔法方法__call__,这个方法可以让类的调用与函数一样。

# -*- coding: utf-8 -*-
class Log:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print('开始执行')
        result = self.func(*args, **kwargs)
        return result

@Log
def greet(name):
    print(f"你好:{name}")
    
greet("有勇气的牛排")

标签:

×
×