[AI编程从入门到入土] 装饰器decorator

AI编程从入门到入土 装饰器decorator

个人导航

知乎:https://www.zhihu.com/people/byzh_rc

CSDN:https://blog.csdn.net/qq_54636039

注:本文仅对所述内容做了框架性引导,具体细节可查询其余相关资料or源码

参考文章:各方资料

文章目录

  • [AI编程从入门到入土 装饰器decorator](#[AI编程从入门到入土] 装饰器decorator)
  • 个人导航
  • 装饰器decorator
        • [1. registration decorator - 情况1](#1. registration decorator - 情况1)
        • [2. registration decorator - 情况2](#2. registration decorator - 情况2)
  • 注册表registry
  • 装饰器工厂
  • [decorator 分类](#decorator 分类)
  • [标准 decorator 模板](#标准 decorator 模板)
        • [1. 类注册decorator](#1. 类注册decorator)
        • [2. 计时器decorator](#2. 计时器decorator)
        • [3. 参数检查decorator](#3. 参数检查decorator)
        • [4. 类decorator](#4. 类decorator)
  • AI训练常用decorator

装饰器decorator

  • registration decorator: 只注册, 不改行为
  • wrapper decorator: 添加行为 (使用wraps)
  • ...
1. registration decorator - 情况1
py 复制代码
@xxx
def test():
  pass

等价于

py 复制代码
def test():
    pass
test = xxx(test)

test 函数先被创建 -> 然后作为参数传给 xxx -> xxx 返回一个新对象 -> 再覆盖原来的 test

此时xxx接收到的参数是func

2. registration decorator - 情况2
py 复制代码
@xxx(abc)
def test():
  pass

等价于

py 复制代码
def test():
    pass
test = xxx(abc)(test)

test 函数先被创建 -> 然后作为参数传给 xxx(abc) -> xxx(abc) 返回一个新对象 -> 再覆盖原来的 test

此时xxx接收到的参数是abc

注册表registry

注册表本质是字典, 装饰器的第一个参数是func:

py 复制代码
# 创建注册表
registry = {}

# 创建装饰器
def register(func):
    registry[func.__name__] = func
    return func

使用:

py 复制代码
@register
def hello():
    print("hello")

@register
def world():
    print("world")

执行后, registry就变成:

py 复制代码
{
    "hello": <function hello>,
    "world": <function world>,
}

就可以如此调用:

py 复制代码
registry["hello"]()

装饰器工厂

py 复制代码
registry = {}

def register(name):

    def decorator(func):
        registry[name] = func
        return func

    return decorator

@register("add")
def func1():
    print("111")
# 等价于: func1 = register("add")(func1)

@register("sub")
def func2():
    print("222")
# 等价于: func2 = register("sub")(func2)

decorator 分类

类型 作用
registration 注册
wrapper 包装行为
cache 缓存
retry 重试
permission 权限
validation 参数校验
singleton 单例
async 异步
transaction 事务
logging 日志
injection 依赖注入

标准 decorator 模板

py 复制代码
from functools import wraps

def decorator(func):

    @wraps(func)
    def wrapper(*args, **kwargs):
        
        # before
        result = func(*args, **kwargs)
        # after
        
        return result

    return wrapper
1. 类注册decorator
py 复制代码
MODELS = {}

def register(name):

    def decorator(cls):
        MODELS[name] = cls
        return cls

    return decorator

@register("resnet")
class resnet:
    ...

@register("lstm")
class lstm:
    ...
2. 计时器decorator
py 复制代码
import time
from functools import wraps

def timer(func):

    @wraps(func)
    def wrapper(*args, **kwargs):

        start = time.time()

        result = func(*args, **kwargs)

        end = time.time()

        print(f"{func.__name__} 耗时: {end - start:.4f}s")

        return result

    return wrapper
3. 参数检查decorator
py 复制代码
from functools import wraps

def check_non_negative(func):

    @wraps(func)
    def wrapper(x):

        if x < 0:
            raise ValueError("不能小于0")

        return func(x)

    return wrapper
4. 类decorator
py 复制代码
from functools import wraps

def enhance(cls):

    # 动态增加类属性
    cls.version = "1.0"
    cls.author = "byzh"
    cls.category = "AI"

    # 动态增加实例方法
    def info(self):
        print("========== INFO ==========")
        print("class    :", cls.__name__)
        print("name     :", self.name)
        print("version  :", cls.version)
        print("author   :", cls.author)
        print("category :", cls.category)
    cls.info = info

    return cls

AI训练常用decorator

py 复制代码
def benchmark(func):

    @wraps(func)
    def wrapper(*args, **kwargs):

        import tracemalloc
        import time

        tracemalloc.start()

        start = time.time()

        result = func(*args, **kwargs)

        current, peak = tracemalloc.get_traced_memory()

        end = time.time()

        print(f"time={end-start}")
        print(f"peak={peak/1024/1024:.2f}MB")

        return result

    return wrapper
相关推荐
威哥爱编程23 分钟前
模拟面试智能体开发实战 05:给面试官接上题库和检索,题目结构化、大纲可溯源,AI 不再凭印象出题
python·agent·harmonyos
ZzT24 分钟前
装了太多 Skill 后 AI 开始「装瞎」?实测 Claude Code 与 Codex 的技能清单预算机制
ai编程·claude
威哥爱编程25 分钟前
模拟面试智能体开发实战 06:答得好怎么追问、答得错怎么点破,追问引擎让面试官会深挖会纠错
python·agent·harmonyos
码间留白1 小时前
从怀疑到真香——AI 重构代码后,我不再追求“最合适”,而是做好这两件事:测试和优化
单元测试·ai编程·代码质量·工程效率·ai重构代码
codists1 小时前
《crafting interpreters》阅读笔记:4.6.2
python
2601_967979121 小时前
机器学习必修课:经典算法与Python实战
python·算法·机器学习·实战·课程
ClouGence1 小时前
开挂级 AI 玩法:一键复刻同款,生成能自动发布,省去所有部署
aigc·ai编程
SomeOtherTime1 小时前
Rust生命周期介绍(AI回答)
开发语言·后端·rust
程序猿打工仔1 小时前
计算机基础(C语言)考编、专技岗
c语言·开发语言·算法
cpolar技术支持2 小时前
listen(5) 只排得住 5 个连接:第 6 个客户端卡在 connect 超时,进程活着端口却显示假活不放行
python·socket·tcp·cpolar·故障排查